📄 fileio.html
字号:
page cache</i> for usable cached versions of the required database pages before loading it from the database file. If no usable cache entry can be found and the database page data is loaded from the database file, it is cached in the <i>page cache</i> in case the same data is needed again later. Because reading from the database file is assumed to be an order of magnitude faster than reading from main-memory, caching database page content in the <i>page cache</i> to minimize the number of read operations performed on the database file is a significant performance enhancement. <p> The <i>page cache</i> is also used to buffer database write operations. When SQLite is required to modify one of more of the <i>database pages</i> that make up a database file, it first modifies the cached version of the page in the <i>page cache</i>. At that point the page is considered a "dirty" page. At some point later on, the new content of the "dirty" page is copied from the <i>page cache</i> into the database file via the VFS interface. Buffering writes in the <i>page cache</i> can reduce the number of write operations required on the database file (in cases where the same page is updated twice) and allows optimizations based on the assumptions outlined in section <cite>fs_performance</cite>. <p> Database read and write operations, and the way in which they interact with and use the <i>page cache</i>, are described in detail in sections <cite>reading_data</cite> and <cite>writing_data</cite> of this document, respectively. <p> At any one time, the <i>page cache</i> contains zero or more <i>page cache entries</i>, each of which has the following data associated with it: <ul> <li><p> A reference to <b>the associated <i>database connection</i></b>. Each entry in the <i>page cache</i> is associated with a single <i>database connection</i>; the <i>database connection</i> that created the entry. A <i>page cache entry</i> is only ever used by the <i>database connection</i> that created it. Page cache entries are not shared between <i>database connections</i>. <li><p> The <b><i>page number</i></b> of the cached page. Pages are sequentially numbered within a database file starting from page 1 (page 1 begins at byte offset 0). Refer to <cite>ff_sqlitert_requirements</cite> for details. <li><p> The <b>cached data</b>; a blob of data <i>page-size</i> bytes in size. </ul> <p> The first two elements in the list above, the associated <i>database connection</i> and the <i>page number</i>, uniquely identify the <i>page cache entry</i>. At no time may the <i>page cache</i> contain two entries for which both the <i>database connection</i> and <i>page number</i> are identical. Or, put another way, a single <i>database connection</i> never caches more than one copy of a database page within the <i>page cache</i>. <p> At any one time, each <i>page cache entry</i> may be said to be a <i>clean page</i>, a <i>non-writable dirty page</i> or a <i>writable dirty page</i>, according to the following definitions: <ul> <li> <p>A <b><i>clean page</i></b> is one for which the cached data currently matches the contents of the corresponding page of the database file. The page has not been modified since it was loaded from the file. <li> <p>A <b><i>dirty page</i></b> is a <i>page cache entry</i> for which the cached data has been modified since it was loaded from the database file, and so no longer matches the current contents of the corresponding database file page. A <i>dirty page</i> is one that is currently buffering a modification made to the database file as part of a <i>write transaction</i>. <li> <p>Within this document, the term <b><i>non-writable dirty page</i></b> is used specifically to refer to a <i>page cache entry</i> with modified content for which it is not yet safe to update the database file with. It is not safe to update a database file with a buffered write if a power or system failure that occurs during or soon after the update may cause the database to become corrupt following system recovery, according to the assumptions made in section <cite>fs_assumption_details</cite>. <li> <p>A <i>dirty page</i> for which it would be safe to update the corresponding database file page with the modified contents of without risking database corruption is known as a <b><i>writable dirty page</i></b>. </ul> <p> The exact logic used to determine if a <i>page cache entry</i> with modified content is a <i>dirty page</i> or <i>writable page</i> is presented in section <cite>page_cache_algorithms</cite>. <p> Because main-memory is a limited resource, the <i>page cache</i> cannot be allowed to grow indefinitely. As a result, unless all database files opened by database connections within the process are quite small, sometimes data must be discarded from the <i>page cache</i>. In practice this means <i>page cache entries</i> must be purged to make room for new ones. If a <i>page cache entry</i> being removed from the <i>page cache</i> to free main-memory is a <i>dirty page</i>, then its contents must be saved into the database file before it can be discarded without data loss. The following two sub-sections describe the algorithms used by the <i>page cache</i> to determine exactly when existing <i>page cache entries</i> are purged (discarded). <h2>Page Cache Configuration</h2> <p class=todo> Describe the parameters set to configure the page cache limits. <h2 id=page_cache_algorithms>Page Cache Algorithms</h2> <p class=todo> Requirements describing the way in which the configuration parameters are used. About LRU etc.<h1 id=reading_data>Reading Data</h1> <p> In order to return data from the database to the user, for example as the results of a SELECT query, SQLite must at some point read data from the database file. Usually, data is read from the database file in aligned blocks of <i>page-size</i> bytes. The exception is when the database file header fields are being inspected, before the <i>page-size</i> used by the database can be known. <p> With two exceptions, a <i>database connection</i> must have an open transaction (either a <i>read-only transaction</i> or a <i>read/write transaction</i>) on the database before data may be read from the database file. <p> The two exceptions are: <ul> <li> When an attempt is made to read the 100 byte <i>database file header</i> immediately after opening the <i>database connection</i> (see section <cite>open_new_connection</cite>). When this occurs no lock is held on the database file. <li> Data read while in the process of opening a read-only transaction (see section <cite>open_read_only_trans</cite>). These read operations occur after a <i>shared lock</i> is held on the database file. </ul> <p> Once a transaction has been opened, reading data from a database connection is a simple operation. Using the xRead() method of the file-handle open on the database file, the required database file pages are read one at a time. SQLite never reads partial pages and always uses a single call to xRead() for each required page. <p> After reading the data for a database page, SQLite stores the raw page of data in the <i>page cache</i>. Each time a page of data is required by the upper layers, the <i>page cache</i> is queried to see if it contains a copy of the required page stored by the current <i>database connection</i>. If such an entry can be found, then the required data is read from the <i>page cache</i> instead of the database file. Only a connection with an open transaction transaction (either a <i>read-only transaction</i> or a <i>read/write transaction</i>) on the database may read data from the <i>page cache</i>. In this sense reading from the <i>page cache</i> is no different to reading from the <i>database file</i>. <p> Refer to section <cite>page_cache_algorithms</cite> for a description of exactly how and for how long page data is stored in the <i>page cache</i>.<p class=req id=H21001> Except for the read operation required by H21007 and those reads made as part of opening a read-only transaction, SQLite shall ensure that a <i>database connection</i> has an open read-only or read/write transaction when any data is read from the <i>database file</i>.</p><p class=req id=H21002> Aside from those read operations described by H21007 and H21XXX, SQLite shall read data from the database file in aligned blocks of <i>page-size</i> bytes, where <i>page-size</i> is the database page size used by the database file.</p><p class=req id=H21042> SQLite shall ensure that a <i>database connection</i> has an open read-only or read/write transaction before using data stored in the <i>page cache</i> to satisfy user queries.</p> <h2 id=open_read_only_trans>Opening a Read-Only Transaction</h2> <p> Before data may be read from a <i>database file</i> or queried from the <i>page cache</i>, a <i>read-only transaction</i> must be successfully opened by the associated database connection (this is true even if the connection will eventually write to the database, as a <i>read/write transaction</i> may only be opened by upgrading from a <i>read-only transaction</i>). This section describes the procedure for opening a <i>read-only transaction</i>. <p> The key element of a <i>read-only transaction</i> is that the file-handle open on the database file obtains and holds a <i>shared-lock</i> on the database file. Because a connection requires an <i>exclusive-lock</i> before it may actually modify the contents of the database file, and by definition while one connection is holding a <i>shared-lock</i> no other connection may hold an <i>exclusive-lock</i>, holding a <i>shared-lock</i> guarantees that no other process may modify the database file while the <i>read-only transaction</i> remains open. This ensures that <i>read-only transactions</i> are sufficiently isolated from the transactions of other database users (see section <cite>overview</cite>). <p>Obtaining the <i>shared lock</i> itself on the database file is quite simple, SQLite just calls the xLock() method of the database file handle. Some of the other processes that take place as part of opening the <i>read-only transaction</i> are quite complex. The steps that SQLite is required to take to open a <i>read-only transaction</i>, in the order in which they must occur, is as follows: <ol> <li>A <i>shared-lock</i> is obtained on the database file. <li>The connection checks if a <i>hot journal file</i> exists in the file-system. If one does, then it is rolled back before continuing. <li>The connection checks if the data in the <i>page cache</i> may still be trusted. If not, all page cache data is discarded. <li>If the file-size is not zero bytes and the page cache does not contain valid data for the first page of the database, then the data for the first page must be read from the database. </ol> <p> Of course, an error may occur while attempting any of the 4 steps enumerated above. If this happens, then the <i>shared-lock</i> is released (if it was obtained) and an error returned to the user. Step 2 of the procedure above is described in more detail in section <cite>hot_journal_detection</cite>. Section <cite>cache_validation</cite> describes the process identified by step 3 above. Further detail on step 4 may be found in section <cite>read_page_one</cite>.<p class=req id=H21010> When required to open a <i>read-only transaction</i> using a <i>database connection</i>, SQLite shall first attempt to obtain a <i>shared-lock</i> on the file-handle open on the database file.</p><p class=req id=H21011> If, while opening a <i>read-only transaction</i>, SQLite fails to obtain the <i>shared-lock</i> on the database file, then the process is abandoned, no transaction is opened and an error returned to the user.</p> <p> The most common reason an attempt to obtain a <i>shared-lock</i> may fail is that some other connection is holding an <i>exclusive</i> or <i>pending lock</i>. However it may also fail because some other error (e.g. an IO or comms related error) occurs within the call to the xLock() method.<p class=req id=H21003> While opening a <i>read-only transaction</i>, after successfully obtaining a <i>shared lock</i> on the database file, SQLite shall attempt to detect and roll back a <i>hot journal file</i> associated with the same database file.</p><p class=req id=H21012> If, while opening a <i>read-only transaction</i>, SQLite encounters
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -