Add code to reduce rollback journal i/o based on IOCAP flags. As yet untested. (CVS 4278)
FossilOrigin-Name: 595568492e63822caed5b6970542dcee4615dc4d
This commit is contained in:
parent
863c0f9b87
commit
4cd2cd5c69
12
manifest
12
manifest
@ -1,5 +1,5 @@
|
||||
C Ensure\stemporary\sfiles\sare\sdeleted\swhen\sthey\sare\sclosed.\s(CVS\s4277)
|
||||
D 2007-08-23T11:47:59
|
||||
C Add\scode\sto\sreduce\srollback\sjournal\si/o\sbased\son\sIOCAP\sflags.\sAs\syet\suntested.\s(CVS\s4278)
|
||||
D 2007-08-23T14:48:24
|
||||
F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
|
||||
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@ -115,7 +115,7 @@ F src/os_unix.c 3ff776e03535b64df12dcc272a913a52d69f3e4a
|
||||
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
|
||||
F src/os_win.c 29c0e19c1072679a4c7818c49fab2f35d2ad7747
|
||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||
F src/pager.c 896e95aa2dcb74d5b951a87be4eec811617c835b
|
||||
F src/pager.c 0879439873a9da769ee400b3b8c0967afd786fe8
|
||||
F src/pager.h 53087c6fb9db01aed17c7fd044662a27507e89b8
|
||||
F src/parse.y 2d2ce439dc6184621fb0b86f4fc5aca7f391a590
|
||||
F src/pragma.c 9b989506a1b7c8aecd6befb8235e2f57a4aba7e5
|
||||
@ -560,7 +560,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||
P 5f0fb894f44069c4aa9b8dba62b4d8a262c991de
|
||||
R 22b54f8709250bd737f996dad2021c82
|
||||
P cf4e3c158aa71afc91f263a314c2e750d191fb41
|
||||
R 48618499cdb378fd88ded4f7882609ca
|
||||
U danielk1977
|
||||
Z fa59609801ef669b738463099d997068
|
||||
Z c7849b12c2cdd0aee60800e4b6323c91
|
||||
|
@ -1 +1 @@
|
||||
cf4e3c158aa71afc91f263a314c2e750d191fb41
|
||||
595568492e63822caed5b6970542dcee4615dc4d
|
84
src/pager.c
84
src/pager.c
@ -18,7 +18,7 @@
|
||||
** file simultaneously, or one process from reading the database while
|
||||
** another is writing.
|
||||
**
|
||||
** @(#) $Id: pager.c,v 1.370 2007/08/23 11:47:59 danielk1977 Exp $
|
||||
** @(#) $Id: pager.c,v 1.371 2007/08/23 14:48:24 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_DISKIO
|
||||
#include "sqliteInt.h"
|
||||
@ -822,17 +822,37 @@ static int writeJournalHdr(Pager *pPager){
|
||||
seekJournalHdr(pPager);
|
||||
pPager->journalHdr = pPager->journalOff;
|
||||
|
||||
/* FIX ME:
|
||||
**
|
||||
** Possibly for a pager not in no-sync mode, the journal magic should not
|
||||
** be written until nRec is filled in as part of next syncJournal().
|
||||
**
|
||||
** Actually maybe the whole journal header should be delayed until that
|
||||
** point. Think about this.
|
||||
*/
|
||||
memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
|
||||
/* The nRec Field. 0xFFFFFFFF for no-sync journals. */
|
||||
put32bits(&zHeader[sizeof(aJournalMagic)], pPager->noSync ? 0xffffffff : 0);
|
||||
|
||||
/*
|
||||
** Write the nRec Field - the number of page records that follow this
|
||||
** journal header. Normally, zero is written to this value at this time.
|
||||
** After the records are added to the journal (and the journal synced,
|
||||
** if in full-sync mode), the zero is overwritten with the true number
|
||||
** of records (see syncJournal()).
|
||||
**
|
||||
** A faster alternative is to write 0xFFFFFFFF to the nRec field. When
|
||||
** reading the journal this value tells SQLite to assume that the
|
||||
** rest of the journal file contains valid page records. This assumption
|
||||
** is dangerous, as if a failure occured whilst writing to the journal
|
||||
** file it may contain some garbage data. There are two scenarios
|
||||
** where this risk can be ignored:
|
||||
**
|
||||
** * When the pager is in no-sync mode. Corruption can follow a
|
||||
** power failure in this case anyway.
|
||||
**
|
||||
** * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees
|
||||
** that garbage data is never appended to the journal file.
|
||||
*/
|
||||
assert(pPager->fd->pMethods||pPager->noSync);
|
||||
if( (pPager->noSync)
|
||||
|| (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
|
||||
){
|
||||
put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff);
|
||||
}else{
|
||||
put32bits(&zHeader[sizeof(aJournalMagic)], 0);
|
||||
}
|
||||
|
||||
/* The random check-hash initialiser */
|
||||
sqlite3Randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
|
||||
put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit);
|
||||
@ -2484,7 +2504,12 @@ int sqlite3PagerRef(DbPage *pPg){
|
||||
** is synced, then the nRec field is updated, then a second sync occurs.
|
||||
**
|
||||
** For temporary databases, we do not care if we are able to rollback
|
||||
** after a power failure, so sync occurs.
|
||||
** after a power failure, so no sync occurs.
|
||||
**
|
||||
** If the IOCAP_SEQUENTIAL flag is set for the persistent media on which
|
||||
** the database is stored, then OsSync() is never called on the journal
|
||||
** file. In this case all that is required is to update the nRec field in
|
||||
** the journal header.
|
||||
**
|
||||
** This routine clears the needSync field of every page current held in
|
||||
** memory.
|
||||
@ -2493,12 +2518,15 @@ static int syncJournal(Pager *pPager){
|
||||
PgHdr *pPg;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
|
||||
/* Sync the journal before modifying the main database
|
||||
** (assuming there is a journal and it needs to be synced.)
|
||||
*/
|
||||
if( pPager->needSync ){
|
||||
if( !pPager->tempFile ){
|
||||
int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
|
||||
assert( pPager->journalOpen );
|
||||
|
||||
/* assert( !pPager->noSync ); // noSync might be set if synchronous
|
||||
** was turned off after the transaction was started. Ticket #615 */
|
||||
#ifndef NDEBUG
|
||||
@ -2512,15 +2540,20 @@ static int syncJournal(Pager *pPager){
|
||||
assert( pPager->journalOff==jSz );
|
||||
}
|
||||
#endif
|
||||
{
|
||||
i64 jrnlOff;
|
||||
|
||||
if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
|
||||
/* Write the nRec value into the journal file header. If in
|
||||
** full-synchronous mode, sync the journal first. This ensures that
|
||||
** all data has really hit the disk before nRec is updated to mark
|
||||
** it as a candidate for rollback.
|
||||
** it as a candidate for rollback.
|
||||
**
|
||||
** This is not required if the persistent media supports the
|
||||
** SAFE_APPEND property. Because in this case it is not possible
|
||||
** for garbage data to be appended to the file, the nRec field
|
||||
** is populated with 0xFFFFFFFF when the journal header is written
|
||||
** and never needs to be updated.
|
||||
*/
|
||||
if( pPager->fullSync ){
|
||||
i64 jrnlOff;
|
||||
if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
|
||||
PAGERTRACE2("SYNC journal of %d\n", PAGERID(pPager));
|
||||
IOTRACE(("JSYNC %p\n", pPager))
|
||||
rc = sqlite3OsSync(pPager->jfd, pPager->sync_flags);
|
||||
@ -2532,12 +2565,14 @@ static int syncJournal(Pager *pPager){
|
||||
rc = write32bits(pPager->jfd, jrnlOff, pPager->nRec);
|
||||
if( rc ) return rc;
|
||||
}
|
||||
PAGERTRACE2("SYNC journal of %d\n", PAGERID(pPager));
|
||||
IOTRACE(("JSYNC %p\n", pPager))
|
||||
rc = sqlite3OsSync(pPager->jfd, pPager->sync_flags|
|
||||
(pPager->sync_flags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0)
|
||||
);
|
||||
if( rc!=0 ) return rc;
|
||||
if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
|
||||
PAGERTRACE2("SYNC journal of %d\n", PAGERID(pPager));
|
||||
IOTRACE(("JSYNC %p\n", pPager))
|
||||
rc = sqlite3OsSync(pPager->jfd, pPager->sync_flags|
|
||||
(pPager->sync_flags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0)
|
||||
);
|
||||
if( rc!=0 ) return rc;
|
||||
}
|
||||
pPager->journalStarted = 1;
|
||||
}
|
||||
pPager->needSync = 0;
|
||||
@ -2774,11 +2809,12 @@ static int pager_recycle(Pager *pPager, int syncOk, PgHdr **ppPg){
|
||||
** it can't be helped.
|
||||
*/
|
||||
if( pPg==0 && pPager->pFirst && syncOk && !MEMDB){
|
||||
int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
|
||||
int rc = syncJournal(pPager);
|
||||
if( rc!=0 ){
|
||||
return rc;
|
||||
}
|
||||
if( pPager->fullSync ){
|
||||
if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
|
||||
/* If in full-sync mode, write a new journal header into the
|
||||
** journal file. This is done to avoid ever modifying a journal
|
||||
** header that is involved in the rollback of pages that have
|
||||
|
Loading…
x
Reference in New Issue
Block a user