748 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			748 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html>
 | |
| <html><head>
 | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | |
| <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 | |
| <link href="sqlite.css" rel="stylesheet">
 | |
| <title>How To Corrupt An SQLite Database File</title>
 | |
| <!-- path= -->
 | |
| </head>
 | |
| <body>
 | |
| <div class=nosearch>
 | |
| <a href="index.html">
 | |
| <img class="logo" src="images/sqlite370_banner.gif" alt="SQLite" border="0">
 | |
| </a>
 | |
| <div><!-- IE hack to prevent disappearing logo --></div>
 | |
| <div class="tagline desktoponly">
 | |
| Small. Fast. Reliable.<br>Choose any three.
 | |
| </div>
 | |
| <div class="menu mainmenu">
 | |
| <ul>
 | |
| <li><a href="index.html">Home</a>
 | |
| <li class='mobileonly'><a href="javascript:void(0)" onclick='toggle_div("submenu")'>Menu</a>
 | |
| <li class='wideonly'><a href='about.html'>About</a>
 | |
| <li class='desktoponly'><a href="docs.html">Documentation</a>
 | |
| <li class='desktoponly'><a href="download.html">Download</a>
 | |
| <li class='wideonly'><a href='copyright.html'>License</a>
 | |
| <li class='desktoponly'><a href="support.html">Support</a>
 | |
| <li class='desktoponly'><a href="prosupport.html">Purchase</a>
 | |
| <li class='search' id='search_menubutton'>
 | |
| <a href="javascript:void(0)" onclick='toggle_search()'>Search</a>
 | |
| </ul>
 | |
| </div>
 | |
| <div class="menu submenu" id="submenu">
 | |
| <ul>
 | |
| <li><a href='about.html'>About</a>
 | |
| <li><a href='docs.html'>Documentation</a>
 | |
| <li><a href='download.html'>Download</a>
 | |
| <li><a href='support.html'>Support</a>
 | |
| <li><a href='prosupport.html'>Purchase</a>
 | |
| </ul>
 | |
| </div>
 | |
| <div class="searchmenu" id="searchmenu">
 | |
| <form method="GET" action="search">
 | |
| <select name="s" id="searchtype">
 | |
| <option value="d">Search Documentation</option>
 | |
| <option value="c">Search Changelog</option>
 | |
| </select>
 | |
| <input type="text" name="q" id="searchbox" value="">
 | |
| <input type="submit" value="Go">
 | |
| </form>
 | |
| </div>
 | |
| </div>
 | |
| <script>
 | |
| function toggle_div(nm) {
 | |
| var w = document.getElementById(nm);
 | |
| if( w.style.display=="block" ){
 | |
| w.style.display = "none";
 | |
| }else{
 | |
| w.style.display = "block";
 | |
| }
 | |
| }
 | |
| function toggle_search() {
 | |
| var w = document.getElementById("searchmenu");
 | |
| if( w.style.display=="block" ){
 | |
| w.style.display = "none";
 | |
| } else {
 | |
| w.style.display = "block";
 | |
| setTimeout(function(){
 | |
| document.getElementById("searchbox").focus()
 | |
| }, 30);
 | |
| }
 | |
| }
 | |
| function div_off(nm){document.getElementById(nm).style.display="none";}
 | |
| window.onbeforeunload = function(e){div_off("submenu");}
 | |
| /* Disable the Search feature if we are not operating from CGI, since */
 | |
| /* Search is accomplished using CGI and will not work without it. */
 | |
| if( !location.origin || !location.origin.match || !location.origin.match(/http/) ){
 | |
| document.getElementById("search_menubutton").style.display = "none";
 | |
| }
 | |
| /* Used by the Hide/Show button beside syntax diagrams, to toggle the */
 | |
| function hideorshow(btn,obj){
 | |
| var x = document.getElementById(obj);
 | |
| var b = document.getElementById(btn);
 | |
| if( x.style.display!='none' ){
 | |
| x.style.display = 'none';
 | |
| b.innerHTML='show';
 | |
| }else{
 | |
| x.style.display = '';
 | |
| b.innerHTML='hide';
 | |
| }
 | |
| return false;
 | |
| }
 | |
| </script>
 | |
| </div>
 | |
| <div class=fancy>
 | |
| <div class=nosearch>
 | |
| <div class="fancy_title">
 | |
| How To Corrupt An SQLite Database File
 | |
| </div>
 | |
| <div class="fancy_toc">
 | |
| <a onclick="toggle_toc()">
 | |
| <span class="fancy_toc_mark" id="toc_mk">►</span>
 | |
| Table Of Contents
 | |
| </a>
 | |
| <div id="toc_sub"><div class="fancy-toc1"><a href="#_file_overwrite_by_a_rogue_thread_or_process">1.  File overwrite by a rogue thread or process</a></div>
 | |
| <div class="fancy-toc2"><a href="#_continuing_to_use_a_file_descriptor_after_it_has_been_closed">1.1.  Continuing to use a file descriptor after it has been closed</a></div>
 | |
| <div class="fancy-toc2"><a href="#_backup_or_restore_while_a_transaction_is_active">1.2.  Backup or restore while a transaction is active</a></div>
 | |
| <div class="fancy-toc2"><a href="#_deleting_a_hot_journal">1.3.  Deleting a hot journal</a></div>
 | |
| <div class="fancy-toc2"><a href="#_mispairing_database_files_and_hot_journals_">1.4.  Mispairing database files and hot journals </a></div>
 | |
| <div class="fancy-toc1"><a href="#_file_locking_problems">2.  File locking problems</a></div>
 | |
| <div class="fancy-toc2"><a href="#_filesystems_with_broken_or_missing_lock_implementations">2.1.  Filesystems with broken or missing lock implementations</a></div>
 | |
| <div class="fancy-toc2"><a href="#_posix_advisory_locks_canceled_by_a_separate_thread_doing_close_">2.2.  Posix advisory locks canceled by a separate thread doing close()</a></div>
 | |
| <div class="fancy-toc3"><a href="#multiple_copies_of_sqlite_linked_into_the_same_application">2.2.1. Multiple copies of SQLite linked into the same application</a></div>
 | |
| <div class="fancy-toc2"><a href="#_two_processes_using_different_locking_protocols">2.3.  Two processes using different locking protocols</a></div>
 | |
| <div class="fancy-toc2"><a href="#_unlinking_or_renaming_a_database_file_while_in_use">2.4.  Unlinking or renaming a database file while in use</a></div>
 | |
| <div class="fancy-toc2"><a href="#_multiple_links_to_the_same_file">2.5.  Multiple links to the same file</a></div>
 | |
| <div class="fancy-toc2"><a href="#_carrying_an_open_database_connection_across_a_fork_">2.6.  Carrying an open database connection across a fork() </a></div>
 | |
| <div class="fancy-toc1"><a href="#_failure_to_sync">3.  Failure to sync</a></div>
 | |
| <div class="fancy-toc2"><a href="#_disk_drives_that_do_not_honor_sync_requests">3.1.  Disk drives that do not honor sync requests</a></div>
 | |
| <div class="fancy-toc2"><a href="#_disabling_sync_using_pragmas">3.2.  Disabling sync using PRAGMAs</a></div>
 | |
| <div class="fancy-toc1"><a href="#_disk_drive_and_flash_memory_failures">4.  Disk Drive and Flash Memory Failures</a></div>
 | |
| <div class="fancy-toc2"><a href="#_non_powersafe_flash_memory_controllers">4.1.  Non-powersafe flash memory controllers</a></div>
 | |
| <div class="fancy-toc2"><a href="#_fake_capacity_usb_sticks">4.2.  Fake capacity USB sticks</a></div>
 | |
| <div class="fancy-toc1"><a href="#_memory_corruption">5.  Memory corruption</a></div>
 | |
| <div class="fancy-toc1"><a href="#_other_operating_system_problems">6.  Other operating system problems</a></div>
 | |
| <div class="fancy-toc2"><a href="#_linux_threads">6.1.  Linux Threads</a></div>
 | |
| <div class="fancy-toc2"><a href="#_failures_of_mmap_on_qnx">6.2.  Failures of mmap() on QNX</a></div>
 | |
| <div class="fancy-toc2"><a href="#_filesystem_corruption">6.3.  Filesystem Corruption</a></div>
 | |
| <div class="fancy-toc1"><a href="#sqlite_configuration_errors">7. SQLite Configuration Errors</a></div>
 | |
| <div class="fancy-toc1"><a href="#_bugs_in_sqlite">8.  Bugs in SQLite</a></div>
 | |
| <div class="fancy-toc2"><a href="#_false_corruption_reports_due_to_database_shrinkage">8.1.  False corruption reports due to database shrinkage</a></div>
 | |
| <div class="fancy-toc2"><a href="#_corruption_following_switches_between_rollback_and_wal_modes">8.2.  Corruption following switches between rollback and WAL modes</a></div>
 | |
| <div class="fancy-toc2"><a href="#_i_o_error_while_obtaining_a_lock_leads_to_corruption">8.3.  I/O error while obtaining a lock leads to corruption</a></div>
 | |
| <div class="fancy-toc2"><a href="#_database_pages_leak_from_the_free_page_list">8.4.  Database pages leak from the free page list</a></div>
 | |
| <div class="fancy-toc2"><a href="#_corruption_following_alternating_writes_from_3_6_and_3_7_">8.5.  Corruption following alternating writes from 3.6 and 3.7.</a></div>
 | |
| <div class="fancy-toc2"><a href="#_race_condition_in_recovery_on_windows_system_">8.6.  Race condition in recovery on windows system.</a></div>
 | |
| </div>
 | |
| </div>
 | |
| <script>
 | |
| function toggle_toc(){
 | |
| var sub = document.getElementById("toc_sub")
 | |
| var mk = document.getElementById("toc_mk")
 | |
| if( sub.style.display!="block" ){
 | |
| sub.style.display = "block";
 | |
| mk.innerHTML = "▼";
 | |
| } else {
 | |
| sub.style.display = "none";
 | |
| mk.innerHTML = "►";
 | |
| }
 | |
| }
 | |
| </script>
 | |
| </div>
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| <h2 style="margin-left:1.0em" notoc="1" id="overview"> Overview</h2> 
 | |
| 
 | |
| <p>An SQLite database is highly resistant to corruption.
 | |
| If an application crash, or an operating-system crash, or even
 | |
| a power failure occurs in the middle of a transaction, the partially
 | |
| written transaction should be automatically rolled back the next time
 | |
| the database file is accessed.  The recovery process is fully
 | |
| automatic and does not require any action on the part of the user
 | |
| or the application.
 | |
| </p>
 | |
| 
 | |
| <p>Though SQLite is resistant to database corruption, it is not immune.
 | |
| This document describes the various ways that an SQLite database might
 | |
| go corrupt.</p>
 | |
| 
 | |
| <h1 id="_file_overwrite_by_a_rogue_thread_or_process"><span>1. </span> File overwrite by a rogue thread or process</h1>
 | |
| 
 | |
| <p>SQLite database files are ordinary disk files.
 | |
| That means that any process can open the file and 
 | |
| overwrite it with garbage.  There is nothing that the SQLite
 | |
| library can do to defend against this.</p>
 | |
| 
 | |
| <a name="stalefd"></a>
 | |
| 
 | |
| <h2 id="_continuing_to_use_a_file_descriptor_after_it_has_been_closed"><span>1.1. </span> Continuing to use a file descriptor after it has been closed</h2>
 | |
| 
 | |
| <p>We have seen multiple cases where a file descriptor was open on a file,
 | |
| then that file descriptor was closed and reopened on an SQLite database.
 | |
| Later, some other thread continued to write into the
 | |
| old file descriptor, not realizing that the original file had been closed
 | |
| already.  But because the file descriptor had been reopened by SQLite,
 | |
| the information that was intended to go into the original file ended up
 | |
| overwriting parts of the SQLite database, leading to corruption of the
 | |
| database.</p>
 | |
| 
 | |
| <p>One example of this occurred circa 2013-08-30 on the canonical repository
 | |
| for the <a href="http://www.fossil-scm.org/">Fossil DVCS</a>.  In that event,
 | |
| file descriptor 2 (standard error) was being erroneously closed (by
 | |
| <a href="http://www.stunnel.org/">stunnel</a>, we suspect) prior to 
 | |
| <a href="c3ref/open.html">sqlite3_open_v2()</a> so that the file descriptor used for the
 | |
| repository database file was 2.  Later, an application 
 | |
| bug caused an assert() statement to emit
 | |
| an error message by invoking write(2,...).  But since file descriptor 2 was 
 | |
| now connected to a database file, the error message
 | |
| overwrote part of the database.  To guard against this kind of problem,
 | |
| SQLite <a href="releaselog/3_8_1.html">version 3.8.1</a> (2013-10-17)
 | |
| and later refuse to use low-numbered file descriptors
 | |
| for database files. 
 | |
| (See <a href="compile.html#minimum_file_descriptor">SQLITE_MINIMUM_FILE_DESCRIPTOR</a> for additional information.)</p>
 | |
| 
 | |
| <p>Another example of corruption caused by using a closed file
 | |
| descriptor was 
 | |
| <a href="https://code.facebook.com/posts/313033472212144/debugging-file-corruption-on-ios/">reported by facebook engineers</a> in a blog post on 2014-08-12.</p>
 | |
| 
 | |
| <p>Another example of this error was reported against
 | |
| <a href="https://fossil-scm.org/">Fossil</a> on 2019-07-11.  A file descriptor would
 | |
| be opened for debugging output, but then closed and reopened by SQLite.
 | |
| But the debugging logic continued to write into the original file
 | |
| descriptor. See the
 | |
| <a href="https://fossil-scm.org/forum/forumpost/c51b9a1169">forum discussion</a>
 | |
| for the bug report and a link to the fix.
 | |
| 
 | |
| </p><h2 id="_backup_or_restore_while_a_transaction_is_active"><span>1.2. </span> Backup or restore while a transaction is active</h2>
 | |
| 
 | |
| <p>Systems that run automatic backups in the background might try to
 | |
| make a backup copy of an SQLite database file while it is in the middle
 | |
| of a transaction.  The backup copy then might contain some old and some
 | |
| new content, and thus be corrupt.</p>
 | |
| 
 | |
| <p>The best approach to make reliable backup copies of an SQLite database
 | |
| is to make use of the <a href="backup.html">backup API</a> that is part of the SQLite library.
 | |
| Failing that, it is safe to make a copy of an SQLite database file as long
 | |
| as there are no transactions in progress by any process.  If the previous
 | |
| transaction failed, then it is important that any rollback journal
 | |
| (the <tt>*-journal</tt> file) or write-ahead log (the <tt>*-wal</tt> file)
 | |
| be copied together with the database file itself.</p>
 | |
| 
 | |
| <a name="delhotjrnl"></a>
 | |
| 
 | |
| <h2 id="_deleting_a_hot_journal"><span>1.3. </span> Deleting a hot journal</h2>
 | |
| 
 | |
| <p>SQLite normally stores all content in a single disk file.  However,
 | |
| while performing a transaction, information necessary to recover the
 | |
| database following a crash or power failure is stored in auxiliary
 | |
| journal files.  Such journal files are described as <a href="fileformat2.html#hotjrnl">"hot"</a>.
 | |
| The journal files have the same name as the
 | |
| original database file with the addition
 | |
| of <tt>-journal</tt> or <tt>-wal</tt> suffix.</p>
 | |
| 
 | |
| <p>SQLite must see the journal files in order to recover from a crash
 | |
| or power failure.  If the <a href="fileformat2.html#hotjrnl">hot journal files</a> are moved, deleted, or renamed
 | |
| after a crash or power failure, then automatic recovery will not work
 | |
| and the database may go corrupt.</p>
 | |
| 
 | |
| <p>Another manifestation of this problem is
 | |
| <a href="shortnames.html#db83corrupt">database corruption caused by inconsistent use of 8+3 filenames</a>.</p>
 | |
| 
 | |
| <a name="roguejrnl"></a>
 | |
| 
 | |
| <h2 id="_mispairing_database_files_and_hot_journals_"><span>1.4. </span> Mispairing database files and hot journals </h2>
 | |
| 
 | |
| <p> The previous example is a specific case of a more general problem:
 | |
| The state of an SQLite database is controlled by both the
 | |
| database file and the journal file.  In a quiescent state, the journal
 | |
| file does not exist and only the database file matters.
 | |
| But if the journal file does exist, it must be
 | |
| kept together with the database to avoid corruption.  The following
 | |
| actions are all likely to lead to corruption:
 | |
| </p><ul>
 | |
| <li> Swapping journal files between two different databases.
 | |
| </li><li> Overwritting a journal file with a different journal file.
 | |
| </li><li> Moving a journal file from one database to another.
 | |
| </li><li> Copying a database file without also copying its journal.
 | |
| </li><li> Overwriting a database file with another without also
 | |
|      deleting any hot journal associated with the original database.
 | |
| </li></ul>
 | |
| 
 | |
| <h1 id="_file_locking_problems"><span>2. </span> File locking problems</h1>
 | |
| 
 | |
| <p>SQLite uses file locks on the database file, and on the 
 | |
| <a href="wal.html">write-ahead log</a> or <a href="wal.html">WAL</a> file, to coordinate access between concurrent
 | |
| processes.  Without coordination, two threads or processes might try
 | |
| to make incompatible changes to a database file at the same time,
 | |
| resulting in database corruption.</p>
 | |
| 
 | |
| <h2 id="_filesystems_with_broken_or_missing_lock_implementations"><span>2.1. </span> Filesystems with broken or missing lock implementations</h2>
 | |
| 
 | |
| <p>SQLite depends on the underlying filesystem to do locking as the
 | |
| documentation says it will.  But some filesystems contain bugs in their
 | |
| locking logic such that the locks do not always behave as advertised.
 | |
| This is especially true of network filesystems and NFS in particular.
 | |
| If SQLite is used on a filesystem where the locking primitives contain
 | |
| bugs, and if two or more threads or processes try to access the same
 | |
| database at the same time, then database corruption might result.</p>
 | |
| 
 | |
| <a name="posix_close_bug"></a>
 | |
| 
 | |
| <h2 id="_posix_advisory_locks_canceled_by_a_separate_thread_doing_close_"><span>2.2. </span> Posix advisory locks canceled by a separate thread doing close()</h2>
 | |
| 
 | |
| <p>The default locking mechanism used by SQLite on unix platforms is
 | |
| POSIX advisory locking.  Unfortunately, POSIX advisory locking has design
 | |
| quirks that make it prone to misuse and failure. In particular, any
 | |
| thread in the same process with a file descriptor that is holding a POSIX
 | |
| advisory lock can override that lock using a different file descriptor.
 | |
| One particularly pernicious problem is that the <tt>close()</tt> system
 | |
| call will cancel all POSIX advisory locks on the same file for all
 | |
| threads and all file descriptors in the process.</p>
 | |
| 
 | |
| <p>So, for example, suppose a multi-thread process has
 | |
| two or more threads with separate SQLite database connections to the
 | |
| same database file.  Then a third thread comes along and wants to read
 | |
| something out of that same database file on its own, without using the 
 | |
| SQLite library.
 | |
| The third thread does an <tt>open()</tt>, a <tt>read()</tt> and then
 | |
| a <tt>close()</tt>.
 | |
| One would think this would be harmless.
 | |
| But the <tt>close()</tt> system call caused the
 | |
| locks held on the database by all the other threads to be dropped.  Those
 | |
| other threads have no way of knowing that their locks have just been
 | |
| trashed (POSIX does not provide any mechanism to determine this) and so
 | |
| they keep on running under the assumption that their locks are still valid.
 | |
| This can lead to two or more threads or processes trying to write to the
 | |
| database at the same time, resulting in database corruption.</p>
 | |
| 
 | |
| <p>Note that it is perfectly safe for two or more threads to access the
 | |
| same SQLite database file using the SQLite library.  The unix drivers for
 | |
| SQLite know about the POSIX advisory locking quirks and work around them.
 | |
| This problem only arises when a thread tries to bypass the SQLite library
 | |
| and read the database file directly.</p>
 | |
| 
 | |
| <h3 id="multiple_copies_of_sqlite_linked_into_the_same_application"><span>2.2.1. </span>Multiple copies of SQLite linked into the same application</h3>
 | |
| 
 | |
| <p>As pointed out in the previous paragraph, SQLite takes steps to work
 | |
| around the quirks of POSIX advisory locking.  Part of that work-around involves
 | |
| keeping a global list (mutex protected) of open SQLite database files.
 | |
| But, if multiple copies of SQLite are linked into the same application,
 | |
| then there will be multiple instances of this global list.
 | |
| Database connections opened using one copy of the SQLite library
 | |
| will be unaware of database connections opened using the other copy,
 | |
| and will be unable to work around the POSIX advisory locking quirks.
 | |
| A <tt>close()</tt> operation on one connection might unknowingly 
 | |
| clear the locks on a different database connection, leading to database
 | |
| corruption.</p>
 | |
| 
 | |
| <p>The scenario above sounds far-fetched.
 | |
| But the SQLite developers are aware of at 
 | |
| least one commercial product that was released
 | |
| with exactly this bug.  The vendor came to the SQLite developers seeking
 | |
| help in tracking down some infrequent database corruption issues they were
 | |
| seeing on Linux and Mac.  The problem was eventually traced to the
 | |
| fact that the application was linking against two separate copies of SQLite.
 | |
| The solution was to change the application build procedures to link against
 | |
| just one copy of SQLite instead of two.</p>
 | |
| 
 | |
| <h2 id="_two_processes_using_different_locking_protocols"><span>2.3. </span> Two processes using different locking protocols</h2>
 | |
| 
 | |
| <p>The default locking mechanism used by SQLite on unix platforms is
 | |
| POSIX advisory locking, but there are other options.  By selecting an
 | |
| alternative <a href="c3ref/vfs.html">sqlite3_vfs</a> using the <a href="c3ref/open.html">sqlite3_open_v2()</a> interface, an
 | |
| application can make use of other locking protocols that might be more
 | |
| appropriate to certain filesystems.  For example, dot-file locking might
 | |
| be select for use in an application that has to run on an NFS filesystem
 | |
| that does not support POSIX advisory locking.</p>
 | |
| 
 | |
| <p>It is important that all connections to the same database file use 
 | |
| the same locking protocol.
 | |
| If one application is using POSIX advisory locks and another application
 | |
| is using dot-file locking, then the two applications will not see each
 | |
| other's locks and will not be able to coordinate database access, possibly
 | |
| leading to database corruption.</p>
 | |
| 
 | |
| <a name="unlink"></a>
 | |
| 
 | |
| <h2 id="_unlinking_or_renaming_a_database_file_while_in_use"><span>2.4. </span> Unlinking or renaming a database file while in use</h2>
 | |
| 
 | |
| <p>If two processes have open connections to the same database file and
 | |
| one process closes its connection, unlinks the file, then creates a new
 | |
| database file in its place with the same name and reopens the new file,
 | |
| then the two processes will be talking to different database files with 
 | |
| the same name.  (Note that this is only possible on Posix and Posix-like
 | |
| systems that permit a file to be unlinked while it is still open for
 | |
| reading and writing.  Windows does not allow this to occur.)
 | |
| Since rollback journals and WAL files are based on the name of the database
 | |
| file, the two different database files will share the same rollback
 | |
| journal or WAL file.  A rollback or recovery for one of the databases
 | |
| might use content from the other database, resulting in corruption.
 | |
| A similar problem occurs if a database file is renamed while it is
 | |
| opened and a new file is created with the old name.</p>
 | |
| 
 | |
| <p>In other words, unlinking or renaming an open database file 
 | |
| results in behavior that is undefined and probably undesirable.</p>
 | |
| 
 | |
| <p>Beginning with SQLite <a href="releaselog/3_7_17.html">version 3.7.17</a> (2013-05-20),
 | |
| the unix OS interface will
 | |
| send SQLITE_WARNING messages to the <a href="errlog.html">error log</a> if a database file is unlinked
 | |
| while it is still in use.</p>
 | |
| 
 | |
| <a name="alias"></a>
 | |
| 
 | |
| <h2 id="_multiple_links_to_the_same_file"><span>2.5. </span> Multiple links to the same file</h2>
 | |
| 
 | |
| <p>If a single database file has multiple links (either hard or soft links)
 | |
| then that is just another way of saying that the file has multiple names.
 | |
| If two or more processes open the database using different names, then
 | |
| they will use different rollback journals and WAL files.  That means that
 | |
| if one process crashes, the other process will be unable to recover the
 | |
| transaction in progress because it will be looking in the wrong place
 | |
| for the appropriate journal.</p>
 | |
| 
 | |
| <p>In other words, opening and using a database file that has two or
 | |
| more names results in behavior that is undefined and probably undesirable.</p>
 | |
| 
 | |
| <p>Beginning with SQLite <a href="releaselog/3_7_17.html">version 3.7.17</a> (2013-05-20),
 | |
| the unix OS interface will
 | |
| send SQLITE_WARNING messages to the <a href="errlog.html">error log</a> if a database file has 
 | |
| multiple hard links.</p>
 | |
| 
 | |
| <p>Beginning with SQLite <a href="releaselog/3_10_0.html">version 3.10.0</a> (2016-01-06), 
 | |
| the unix OS interface will
 | |
| attempt to resolve symbolic links and open the database file by its
 | |
| canonical name.  Prior to version 3.10.0, opening a database file 
 | |
| through a symbolic link was similar to opening a database file
 | |
| that had multiple hard links and resulted in undefined behavior.</p>
 | |
| 
 | |
| <a name="fork"></a>
 | |
| 
 | |
| <h2 id="_carrying_an_open_database_connection_across_a_fork_"><span>2.6. </span> Carrying an open database connection across a fork() </h2>
 | |
| 
 | |
| <p> Do not open an SQLite database connection, then fork(), then try
 | |
| to use that database connection in the child process.  All kinds of
 | |
| locking problems will result and you can easily end up with a corrupt
 | |
| database.  SQLite is not designed to support that kind of behavior.
 | |
| Any database connection that is used in a child process must be opened
 | |
| in the child process, not inherited from the parent.
 | |
| 
 | |
| </p><p> Do not even call <a href="c3ref/close.html">sqlite3_close()</a> on a database connection from a
 | |
| child process if the connection was opened in the parent.  It is safe
 | |
| to close the underlying file descriptor, but the <a href="c3ref/close.html">sqlite3_close()</a>
 | |
| interface might invoke cleanup activities that will delete content out
 | |
| from under the parent, leading to errors and perhaps even database
 | |
| corruption.
 | |
| 
 | |
| </p><h1 id="_failure_to_sync"><span>3. </span> Failure to sync</h1>
 | |
| 
 | |
| <p>In order to guarantee that database files are always consistent, SQLite
 | |
| will occasionally ask the operating system to flush all pending writes to
 | |
| persistent storage then wait for that flush to complete.  This is 
 | |
| accomplished using the <tt>fsync()</tt> system call under unix and
 | |
| <tt>FlushFileBuffers()</tt> under Windows.  We call this flush of
 | |
| pending writes a "sync".</p>
 | |
| 
 | |
| <p>Actually, if one is only concerned with atomic and consistent writes and
 | |
| is willing to forego durable writes, the sync operation does not need
 | |
| to wait until the content is completely stored on persistent media.  Instead,
 | |
| the sync operation can be thought of as an I/O barrier.  As long as all
 | |
| writes that occur before the sync are completed before any write that happens
 | |
| after the sync, no database corruption will occur.  If sync is operating as
 | |
| an I/O barrier and not as a true sync, then a power failure or system crash
 | |
| might cause one or more previously committed transactions to roll back
 | |
| (in violation of the "durable" property of "ACID") but the database will at
 | |
| least continue to be consistent, and that is what most people care about.</p>
 | |
| 
 | |
| <h2 id="_disk_drives_that_do_not_honor_sync_requests"><span>3.1. </span> Disk drives that do not honor sync requests</h2>
 | |
| 
 | |
| <p>Unfortunately, most consumer-grade mass storage devices lie about
 | |
| syncing.  Disk drives will report that content is safely on persistent
 | |
| media as soon as it reaches the track buffer and before actually being
 | |
| written to oxide.  This makes the disk drives seem to operate faster
 | |
| (which is vitally important to the manufacturer so that they can show
 | |
| good benchmark numbers in trade magazines).  And in fairness, the lie
 | |
| normally causes no harm, as long as there is no power loss or hard reset
 | |
| prior to the track buffer actually being written to oxide.  But if a
 | |
| power loss or hard reset does occur, and if that results in content that
 | |
| was written after a sync reaching oxide while content written before
 | |
| the sync is still in a track buffer, then database corruption can occur.</p>
 | |
| 
 | |
| <p>USB flash memory sticks seem to be especially pernicious liars 
 | |
| regarding sync requests.  One can easily see this by committing a large
 | |
| transaction to an SQLite database on a USB memory stick.  The COMMIT
 | |
| command will return relatively quickly, indicating that the memory stick
 | |
| has told the operating system and the operating system has told SQLite that
 | |
| all content is safely in persistent storage, and yet the LED on the end
 | |
| of the memory stick will continue flashing for several more seconds. 
 | |
| Pulling out the memory stick while the LED is still flashing will frequently
 | |
| result in database corruption.</p>
 | |
| 
 | |
| <p>Note that SQLite must believe whatever the operating system and hardware
 | |
| tell it about the status of sync requests.  There is no way for SQLite to
 | |
| detect that either is lying and that writes might be occurring out-of-order.
 | |
| However, SQLite in <a href="wal.html">WAL mode</a> is far more forgiving of
 | |
| out-of-order writes than in the default rollback journal modes.  In WAL
 | |
| mode, the only time that a failed sync operation can cause database corruption
 | |
| is during a <a href="wal.html#ckpt">checkpoint</a> operation.  A sync failure during a COMMIT might
 | |
| result in loss of durability but not in a corrupt database file.  Hence,
 | |
| one line of defense against database corruption due to failed sync operations
 | |
| is to use SQLite in WAL mode and to checkpoint as infrequently as possible.</p>
 | |
| 
 | |
| <h2 id="_disabling_sync_using_pragmas"><span>3.2. </span> Disabling sync using PRAGMAs</h2>
 | |
| 
 | |
| <p>The sync operations that SQLite performs to help ensure integrity
 | |
| can be disabled at run-time using the <a href="pragma.html#pragma_synchronous">synchronous pragma</a>.  By setting
 | |
| PRAGMA synchronous=OFF, all sync operations are omitted.  This makes
 | |
| SQLite seem to run faster, but it also allows the operating system to freely
 | |
| reorder writes, which could result in database corruption if a power failure
 | |
| or hard reset occurs prior to all content reaching persistent storage.</p>
 | |
| 
 | |
| <p>For maximum reliability and for robustness against database corruption,
 | |
| SQLite should always be run with its default synchronous setting of FULL.</p>
 | |
| 
 | |
| <a name="hardwarefault"></a>
 | |
| 
 | |
| <h1 id="_disk_drive_and_flash_memory_failures"><span>4. </span> Disk Drive and Flash Memory Failures</h1>
 | |
| 
 | |
| <p>An SQLite database can become corrupt if the file content changes 
 | |
| due to a disk drive or flash memory failure.  It is very rare, but disks 
 | |
| will occasionally flip a bit in the middle of a sector.</p>
 | |
| 
 | |
| <h2 id="_non_powersafe_flash_memory_controllers"><span>4.1. </span> Non-powersafe flash memory controllers</h2>
 | |
| 
 | |
| <p>We are told that in some flash memory controllers the wear-leveling logic
 | |
| can cause random filesystem damage if power is interrupted during a write.
 | |
| This can manifest, for example, as random changes in the middle of a file
 | |
| that was not even open at the time of the power loss.  So, for example,
 | |
| a device would be writing content into an MP3 file in flash memory when a
 | |
| power loss occurs, and that could result in an SQLite database being
 | |
| corrupted even though the database was not even in use at the time of the
 | |
| power loss.</p>
 | |
| 
 | |
| <a name="fakeusb"></a>
 | |
| 
 | |
| <h2 id="_fake_capacity_usb_sticks"><span>4.2. </span> Fake capacity USB sticks</h2>
 | |
| 
 | |
| <p>There are many fraudulent USB sticks in circulation that report to have
 | |
| a high capacity (ex: 8GB) but are really only capable of storing a much
 | |
| smaller amount (ex: 1GB).   Attempts to write on these devices will
 | |
| often result in unrelated files being overwritten.  Any use of a fraudulent
 | |
| flash memory device can easily lead to database corruption, therefore.
 | |
| Internet searches such as "fake capacity usb" will turn up lots of
 | |
| disturbing information about this problem.
 | |
| 
 | |
| </p><h1 id="_memory_corruption"><span>5. </span> Memory corruption</h1>
 | |
| 
 | |
| <p>SQLite is a C-library that runs in the same address space as the 
 | |
| application that it serves.  That means that stray pointers, buffer
 | |
| overruns, heap corruption, or other malfunctions in the application can
 | |
| corrupt internal SQLite data structure and ultimately result in a
 | |
| corrupt database file.  Normally these kinds of problems manifest themselves
 | |
| as segfaults prior to any database corruption occurring, but there have
 | |
| been instances where application code errors have caused SQLite to
 | |
| malfunction subtly so as to corrupt the database file rather than
 | |
| panicking.</p>
 | |
| 
 | |
| <p>The memory corruption problem becomes more acute when
 | |
| using <a href="mmap.html">memory-mapped I/O</a>.
 | |
| When all or part of the database file is mapped into the application's
 | |
| address space, then a stray pointer that overwrites any part of that
 | |
| mapped space will immediately corrupt the database file, without
 | |
| requiring the application to do a subsequent write() system call.</p>
 | |
| 
 | |
| <h1 id="_other_operating_system_problems"><span>6. </span> Other operating system problems</h1>
 | |
| 
 | |
| <p>Sometimes operating systems will exhibit non-standard behavior which
 | |
| can lead to problems.  Sometimes this non-standard behavior is deliberate,
 | |
| and sometimes it is a mistake in the implementation.  But in any event,
 | |
| if the operating performs differently from they way SQLite expects it to
 | |
| perform, the possibility of database corruption exists.</p>
 | |
| 
 | |
| <h2 id="_linux_threads"><span>6.1. </span> Linux Threads</h2>
 | |
| 
 | |
| <p>Some older versions of Linux used the LinuxThreads library for thread
 | |
| support.  LinuxThreads is similar to Pthreads, but is subtly different
 | |
| with respect to handling of POSIX advisory locks.  SQLite versions
 | |
| 2.2.3 through 3.6.23 recognized that LinuxThreads were being used at
 | |
| runtime and took appropriate action to work around the non-standard
 | |
| behavior of LinuxThreads.  But most modern Linux implementations make
 | |
| use of the newer, and correct, NPTL implementation of Pthreads.  Beginning
 | |
| with SQLite <a href="releaselog/3_7_0.html">version 3.7.0</a> (2010-07-21), the use of NPTL is assumed.
 | |
| No checks are 
 | |
| made.  Hence, recent versions of SQLite will subtly malfunction and may 
 | |
| corrupt database files if used in multi-threaded application that run
 | |
| on older linux systems that make use of LinuxThreads.</p>
 | |
| 
 | |
| <h2 id="_failures_of_mmap_on_qnx"><span>6.2. </span> Failures of mmap() on QNX</h2>
 | |
| 
 | |
| <p>There exists some subtle problem with mmap() on QNX such that making
 | |
| a second mmap() call against a single file descriptor can cause
 | |
| the memory obtained from the first mmap() call to be zeroed.  SQLite on
 | |
| unix uses mmap() to create a shared memory region for transaction 
 | |
| coordination in <a href="wal.html">WAL mode</a>, and it will call mmap() multiple times
 | |
| for large transactions.  The QNX mmap() has been demonstrated to corrupt
 | |
| database file under that scenario.  QNX engineers are aware of this problem
 | |
| and are working on a solution; the problem may have already been fixed by
 | |
| the time you read this.</p>
 | |
| 
 | |
| <p>When running on QNX, it is recommended that <a href="mmap.html">memory-mapped I/O</a> never
 | |
| be used.  Furthermore, to use <a href="wal.html">WAL mode</a>, it is recommended that applications
 | |
| employ the <a href="pragma.html#pragma_locking_mode">exclusive locking mode</a> in order to 
 | |
| use <a href="wal.html#noshm">WAL without shared memory</a>.
 | |
| 
 | |
| 
 | |
| <a name="fscorruption"></a>
 | |
| 
 | |
| </p><h2 id="_filesystem_corruption"><span>6.3. </span> Filesystem Corruption</h2>
 | |
| 
 | |
| <p>Since SQLite databases are ordinary disk files, any malfunction in the
 | |
| filesystem can corrupt the database.  Filesystems in modern operating systems
 | |
| are very reliable, but errors do still occur.  For example, on 2013-10-01
 | |
| the SQLite database that holds the
 | |
| <a href="http://wiki.tcl-lang.org/">Wiki for Tcl/Tk</a> went corrupt a few days
 | |
| after the host computer was moved to a dodgy build of the (linux) kernel
 | |
| that had issues in the filesystem layer.  In that event, the filesystem
 | |
| eventually became so badly corrupted that the machine was unusable, but
 | |
| the earliest symptom of trouble was the corrupted SQLite database.</p>
 | |
| 
 | |
| <a name="cfgerr"></a>
 | |
| 
 | |
| <h1 id="sqlite_configuration_errors"><span>7. </span>SQLite Configuration Errors</h1>
 | |
| 
 | |
| <p>SQLite has many built-in protections against database corruption.
 | |
| But many of these protections can be disabled by configuration options.
 | |
| If protections are disabled, database corruption may occur.
 | |
| 
 | |
| </p><p>The following are examples of disabling the built-in protection
 | |
| mechanisms of SQLite:
 | |
| 
 | |
| </p><ul>
 | |
| <li><p>Setting <a href="pragma.html#pragma_synchronous">PRAGMA synchronous=OFF</a> can cause the database to
 | |
| go corrupt if there is an operating-system crash or power failure,
 | |
| though this setting is safe from damage due to application crashes.
 | |
| 
 | |
| </p></li><li><p>Changing the <a href="pragma.html#pragma_schema_version">PRAGMA schema_version</a> while other database
 | |
| connections are open.
 | |
| 
 | |
| </p></li><li><p>Using <a href="pragma.html#pragma_journal_mode">PRAGMA journal_mode=OFF</a> or <a href="pragma.html#pragma_journal_mode">PRAGMA journal_mode=MEMORY</a>
 | |
| and taking an application crash in the middle of a write transaction.
 | |
| 
 | |
| </p></li><li><p>Setting <a href="pragma.html#pragma_writable_schema">PRAGMA writable_schema=ON</a> and then changing the
 | |
| database schema using DML statements can render the database completely
 | |
| unreadable, if not done carefully.
 | |
| </p></li></ul>
 | |
| 
 | |
| <h1 id="_bugs_in_sqlite"><span>8. </span> Bugs in SQLite</h1>
 | |
| 
 | |
| <p>SQLite is <a href="testing.html">very carefully tested</a> to help ensure that it is
 | |
| as bug-free as possible.  Among the many tests that are carried out for
 | |
| every SQLite version are tests that simulate power failures, I/O errors,
 | |
| and out-of-memory (OOM) errors and verify that no database corrupt occurs
 | |
| during any of these events.  SQLite is also field-proven with approximately
 | |
| two billion active deployments with no serious problems.</p>
 | |
| 
 | |
| <p>Nevertheless, no software is 100% perfect.  There have been a few
 | |
| historical bugs in SQLite (now fixed) that could cause database corruption.
 | |
| And there may be yet a few more that remain undiscovered.  Because of the
 | |
| extensive testing and widespread use of SQLite, bugs that result in
 | |
| database corruption tend to be very obscure.  The likelihood
 | |
| of an application encountering an SQLite bug is small.  To illustrate this,
 | |
| an account is given below 
 | |
| of all database-corruption bugs found in SQLite during the
 | |
| four-year period from 2009-04-01 to 2013-04-15.
 | |
| This account should give the reader an intuitive sense of the
 | |
| kinds of bugs in SQLite that manage to slip through testing procedures
 | |
| and make it into a release.</p>
 | |
| 
 | |
| 
 | |
| <h2 id="_false_corruption_reports_due_to_database_shrinkage"><span>8.1. </span> False corruption reports due to database shrinkage</h2>
 | |
| 
 | |
| <p>If a database is written by SQLite version 3.7.0 or later and then
 | |
| written again by SQLite version 3.6.23 or earlier in such a way as to
 | |
| make the size of the database file decrease, then the next time that
 | |
| SQLite version 3.7.0 access the database file, it might report that the
 | |
| database file is corrupt.  The database file is not really corrupt, however.
 | |
| Version 3.7.0 was simply being overly zealous in its corruption detection.</p>
 | |
| 
 | |
| <p>The problem was fixed on 2011-02-20.  The fix first appears in
 | |
| SQLite <a href="releaselog/3_7_6.html">version 3.7.6</a> (2011-04-12).</p>
 | |
| 
 | |
| <h2 id="_corruption_following_switches_between_rollback_and_wal_modes"><span>8.2. </span> Corruption following switches between rollback and WAL modes</h2>
 | |
| 
 | |
| <p>Repeatedly switching an SQLite database in and out of <a href="wal.html">WAL mode</a>
 | |
| and running the <a href="lang_vacuum.html">VACUUM</a> command in between switches, in one process or
 | |
| thread, can cause another process or thread that has the database file
 | |
| open to miss the fact that the database has changed.  That second process
 | |
| or thread might then try to modify the database using a stale cache and
 | |
| cause database corruption.</p>
 | |
| 
 | |
| <p>This problem was discovered during internal testing and has never been
 | |
| observed in the wild.  The problem was fixed on 2011-01-27 and in version
 | |
| 3.7.5.</p>
 | |
| 
 | |
| <h2 id="_i_o_error_while_obtaining_a_lock_leads_to_corruption"><span>8.3. </span> I/O error while obtaining a lock leads to corruption</h2>
 | |
| 
 | |
| <p>If the operating system returns an I/O error while attempting to obtain
 | |
| a certain lock on shared memory in <a href="wal.html">WAL mode</a> then SQLite might fail 
 | |
| to reset its cache,
 | |
| which could lead to database corruption if subsequent writes are attempted.</p>
 | |
| 
 | |
| <p>Note that this problem only occurs if the attempt to acquire the lock
 | |
| resulted in an I/O error.  If the lock is simply not granted (because some
 | |
| other thread or process is already holding a conflicting lock) then no
 | |
| corruption will ever occur.  We are not aware of any operating systems that
 | |
| will fail with an I/O error while attempting to get a file lock on shared
 | |
| memory.  So this is a theoretical problem rather than a real problem.
 | |
| Needless to say, this problem has never been observed in the wild.  The
 | |
| problem was discovered while doing stress testing of SQLite in a test
 | |
| harness that simulates I/O errors.</p>
 | |
| 
 | |
| <p>This problem was fixed on 2010-09-20 for SQLite version 3.7.3.</p>
 | |
| 
 | |
| <h2 id="_database_pages_leak_from_the_free_page_list"><span>8.4. </span> Database pages leak from the free page list</h2>
 | |
| 
 | |
| <p>When content is deleted from an SQLite database, pages that are no
 | |
| longer used are added to a free list and are reused to hold content
 | |
| added by subsequent inserts.  A bug in SQLite that was present in
 | |
| version 3.6.16 through 3.7.2 might cause pages to go missing out of
 | |
| the free list when <a href="pragma.html#pragma_incremental_vacuum">incremental_vacuum</a> was used.  This would not cause
 | |
| data loss.  But it would result in the database file being larger than
 | |
| necessary.  And it would cause the <a href="pragma.html#pragma_integrity_check">integrity_check pragma</a> to report
 | |
| pages missing from the free list.</p>
 | |
| 
 | |
| <p>This problem was fixed on 2010-08-23 for SQLite version 3.7.2.</p>
 | |
| 
 | |
| <h2 id="_corruption_following_alternating_writes_from_3_6_and_3_7_"><span>8.5. </span> Corruption following alternating writes from 3.6 and 3.7.</h2>
 | |
| 
 | |
| <p>SQLite version 3.7.0 introduced a number of new enhancements to
 | |
| the SQLite database file format (such as but not limited to <a href="wal.html">WAL</a>).
 | |
| The 3.7.0 release was a shake-out release for these new features. 
 | |
| We expected to find problems and were not disappointed.</p>
 | |
| 
 | |
| <p>If a database were originally created using SQLite version 3.7.0,
 | |
| then written by SQLite version 3.6.23.1 such that the size of the database
 | |
| file increased, then written again by SQLite version 3.7.0, the database
 | |
| file could go corrupt.</p>
 | |
| 
 | |
| <p>This problem was fixed on 2010-08-04 for SQLite version 3.7.1.</p>
 | |
| 
 | |
| <h2 id="_race_condition_in_recovery_on_windows_system_"><span>8.6. </span> Race condition in recovery on windows system.</h2>
 | |
| 
 | |
| <p>SQLite version 3.7.16.2 fixes a subtle race condition in the locking
 | |
| logic on Windows systems.  When a database file is in need
 | |
| of recovery because the previous process writing to it crashed in the
 | |
| middle of a transaction and two or more processes try to open the 
 | |
| that database at the same time, then the race condition might cause
 | |
| one of those processes to get a false indication that the recovery 
 | |
| has already completed, allowing that process to continue using the
 | |
| database file without running recovery first.  If that process writes
 | |
| to the file, then the file might go corrupt.  This race condition
 | |
| had apparently existed in all prior versions of SQLite for Windows going
 | |
| back to 2004.  But the race was very tight.  Practically speaking, you
 | |
| need a fast multi-core machine in which you launch two processes to run
 | |
| recovery at the same moment on two separate cores.  This defect was
 | |
| on Windows systems only and did not affect the posix OS interface.</p>
 | |
| 
 |