Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add code for the atomic-write optimisation. Disabled by default. (CVS 4268) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
581fadfe31757e3fb97b12f93c1e3c08 |
User & Date: | danielk1977 2007-08-22 11:22:04.000 |
Context
2007-08-22
| ||
11:41 | Get the quick.test script running with SQLITE_THREADSAFE enabled. (CVS 4269) (check-in: 1f28b7e47b user: drh tags: trunk) | |
11:22 | Add code for the atomic-write optimisation. Disabled by default. (CVS 4268) (check-in: 581fadfe31 user: danielk1977 tags: trunk) | |
02:57 | Remove a debugging btree_breakpoint from vtab1.test. (CVS 4267) (check-in: 6cc8641ed2 user: drh tags: trunk) | |
Changes
Changes to main.mk.
︙ | ︙ | |||
53 54 55 56 57 58 59 | # TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src # Object files for the SQLite library. # LIBOBJ+= alter.o analyze.o attach.o auth.o btree.o build.o \ callback.o complete.o date.o delete.o \ | | | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | # TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src # Object files for the SQLite library. # LIBOBJ+= alter.o analyze.o attach.o auth.o btree.o build.o \ callback.o complete.o date.o delete.o \ expr.o func.o hash.o insert.o journal.o loadext.o \ main.o malloc.o mem1.o mem2.o mutex.o \ opcodes.o os.o os_os2.o os_unix.o os_win.o \ pager.o parse.o pragma.o prepare.o printf.o random.o \ select.o table.o tclsqlite.o tokenize.o trigger.o \ update.o util.o vacuum.o \ vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbefifo.o vdbemem.o \ where.o utf.o legacy.o vtab.o |
︙ | ︙ | |||
99 100 101 102 103 104 105 106 107 108 109 110 111 112 | $(TOP)/src/date.c \ $(TOP)/src/delete.c \ $(TOP)/src/expr.c \ $(TOP)/src/func.c \ $(TOP)/src/hash.c \ $(TOP)/src/hash.h \ $(TOP)/src/insert.c \ $(TOP)/src/legacy.c \ $(TOP)/src/loadext.c \ $(TOP)/src/main.c \ $(TOP)/src/malloc.c \ $(TOP)/src/mem1.c \ $(TOP)/src/mem2.c \ $(TOP)/src/mutex.c \ | > | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | $(TOP)/src/date.c \ $(TOP)/src/delete.c \ $(TOP)/src/expr.c \ $(TOP)/src/func.c \ $(TOP)/src/hash.c \ $(TOP)/src/hash.h \ $(TOP)/src/insert.c \ $(TOP)/src/journal.c \ $(TOP)/src/legacy.c \ $(TOP)/src/loadext.c \ $(TOP)/src/main.c \ $(TOP)/src/malloc.c \ $(TOP)/src/mem1.c \ $(TOP)/src/mem2.c \ $(TOP)/src/mutex.c \ |
︙ | ︙ | |||
361 362 363 364 365 366 367 368 369 370 371 372 373 374 | $(TCCX) -c $(TOP)/src/func.c hash.o: $(TOP)/src/hash.c $(HDR) $(TCCX) -c $(TOP)/src/hash.c insert.o: $(TOP)/src/insert.c $(HDR) $(TCCX) -c $(TOP)/src/insert.c legacy.o: $(TOP)/src/legacy.c $(HDR) $(TCCX) -c $(TOP)/src/legacy.c loadext.o: $(TOP)/src/loadext.c $(HDR) $(TCCX) -c $(TOP)/src/loadext.c | > > > | 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | $(TCCX) -c $(TOP)/src/func.c hash.o: $(TOP)/src/hash.c $(HDR) $(TCCX) -c $(TOP)/src/hash.c insert.o: $(TOP)/src/insert.c $(HDR) $(TCCX) -c $(TOP)/src/insert.c journal.o: $(TOP)/src/journal.c $(HDR) $(TCCX) -c $(TOP)/src/journal.c legacy.o: $(TOP)/src/legacy.c $(HDR) $(TCCX) -c $(TOP)/src/legacy.c loadext.o: $(TOP)/src/loadext.c $(HDR) $(TCCX) -c $(TOP)/src/loadext.c |
︙ | ︙ |
Added src/journal.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | /* ** 2007 August 22 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** @(#) $Id: journal.c,v 1.1 2007/08/22 11:22:04 danielk1977 Exp $ */ #ifdef SQLITE_ENABLE_ATOMIC_WRITE /* ** This file implements a special kind of sqlite3_file object used ** by SQLite to create journal files if the atomic-write optimization ** is enabled. ** ** The distinctive characteristic of this sqlite3_file is that the ** actual on disk file is created lazily. When the file is created, ** the caller specifies a buffer size for an in-memory buffer to ** be used to service read() and write() requests. The actual file ** on disk is not created or populated until either: ** ** 1) The in-memory representation grows too large for the allocated ** buffer, or ** 2) The xSync() method is called. */ #include "sqliteInt.h" struct JournalFile { sqlite3_io_methods *pMethod; int nBuf; char *zBuf; int iSize; int flags; sqlite3_vfs *pVfs; sqlite3_file *pReal; const char *zJournal; }; typedef struct JournalFile JournalFile; /* ** If it does not already exists, create and populate the on-disk file ** for JournalFile p. */ static int createFile(JournalFile *p){ int rc = SQLITE_OK; if( !p->pReal ){ p->pReal = (sqlite3_file *)&p[1]; rc = sqlite3OsOpen(p->pVfs, p->zJournal, p->pReal, p->flags, 0); if( rc==SQLITE_OK && p->iSize>0 ){ assert(p->iSize<=p->nBuf); rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0); } } return rc; } /* ** Close the file. */ static int jrnlClose(sqlite3_file *pJfd){ JournalFile *p = (JournalFile *)pJfd; if( p->pReal ){ sqlite3OsClose(p->pReal); } sqlite3_free(p->zBuf); return SQLITE_OK; } /* ** Read data from the file. */ static int jrnlRead( sqlite3_file *pJfd, void *zBuf, int iAmt, sqlite_int64 iOfst ){ int rc = SQLITE_OK; JournalFile *p = (JournalFile *)pJfd; if( p->pReal ){ rc = sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst); }else{ int n = iAmt; memset(zBuf, 0, n); if( n+iOfst>p->iSize ){ rc = SQLITE_IOERR_SHORT_READ; }else{ memcpy(zBuf, &p->zBuf[iOfst], n); } } return rc; } /* ** Write data to the file. */ static int jrnlWrite( sqlite3_file *pJfd, const void *zBuf, int iAmt, sqlite_int64 iOfst ){ int rc = SQLITE_OK; JournalFile *p = (JournalFile *)pJfd; if( !p->pReal && (iOfst+iAmt)>p->nBuf ){ rc = createFile(p); } if( rc==SQLITE_OK ){ if( p->pReal ){ rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst); }else{ memcpy(&p->zBuf[iOfst], zBuf, iAmt); if( p->iSize<(iOfst+iAmt) ){ p->iSize = (iOfst+iAmt); } } } return rc; } /* ** Truncate the file. */ static int jrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ int rc = SQLITE_OK; JournalFile *p = (JournalFile *)pJfd; if( p->pReal ){ rc = sqlite3OsTruncate(p->pReal, size); }else if( size>p->iSize ){ p->iSize = size; } return rc; } /* ** Sync the file. */ static int jrnlSync(sqlite3_file *pJfd, int flags){ int rc; JournalFile *p = (JournalFile *)pJfd; rc = createFile(p); if( rc==SQLITE_OK ){ rc = sqlite3OsSync(p->pReal, flags); } return rc; } /* ** Query the size of the file in bytes. */ static int jrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){ int rc = SQLITE_OK; JournalFile *p = (JournalFile *)pJfd; if( p->pReal ){ rc = sqlite3OsFileSize(p->pReal, pSize); }else{ *pSize = (sqlite_int64) p->iSize; } return rc; } /* ** Table of methods for JournalFile sqlite3_file object. */ static struct sqlite3_io_methods JournalFileMethods = { 1, /* iVersion */ jrnlClose, /* xClose */ jrnlRead, /* xRead */ jrnlWrite, /* xWrite */ jrnlTruncate, /* xTruncate */ jrnlSync, /* xSync */ jrnlFileSize, /* xFileSize */ 0, /* xLock */ 0, /* xUnlock */ 0, /* xCheckReservedLock */ 0, /* xBreakLock */ 0, /* xLockState */ 0, /* xSectorSize */ 0 /* xDeviceCharacteristics */ }; /* ** Open a journal file. */ int sqlite3JournalOpen( sqlite3_vfs *pVfs, const char *zName, sqlite3_file *pJfd, int flags, int nBuf ){ JournalFile *p = (JournalFile *)pJfd; memset(p, 0, sqlite3JournalSize(pVfs)); if( nBuf>0 ){ p->zBuf = sqlite3MallocZero(nBuf); if( !p->zBuf ){ return SQLITE_NOMEM; } }else{ return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0); } p->pMethod = &JournalFileMethods; p->nBuf = nBuf; p->flags = flags; p->zJournal = zName; p->pVfs = pVfs; return SQLITE_OK; } /* ** Return the number of bytes required to store a JournalFile that uses vfs ** pVfs to create the underlying on-disk files. */ int sqlite3JournalSize(sqlite3_vfs *pVfs){ return (pVfs->szOsFile+sizeof(JournalFile)); } #endif |
Changes to src/os.c.
︙ | ︙ | |||
20 21 22 23 24 25 26 | /* ** The following routines are convenience wrappers around methods ** of the sqlite3_file object. This is mostly just syntactic sugar. All ** of this would be completely automatic if SQLite were coded using ** C++ instead of plain old C. */ int sqlite3OsClose(sqlite3_file *pId){ | > | | > > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | /* ** The following routines are convenience wrappers around methods ** of the sqlite3_file object. This is mostly just syntactic sugar. All ** of this would be completely automatic if SQLite were coded using ** C++ instead of plain old C. */ int sqlite3OsClose(sqlite3_file *pId){ int rc = SQLITE_OK; if( pId->pMethods ){ rc = pId->pMethods->xClose(pId); pId->pMethods = 0; } return rc; } int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){ return id->pMethods->xRead(id, pBuf, amt, offset); } int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){ return id->pMethods->xWrite(id, pBuf, amt, offset); } |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.366 2007/08/22 11:22:04 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include <assert.h> #include <string.h> /* |
︙ | ︙ | |||
599 600 601 602 603 604 605 606 607 608 609 610 611 612 | static int osUnlock(sqlite3_file *pFd, int eLock){ if( !pFd->pMethods ){ return SQLITE_OK; } return sqlite3OsUnlock(pFd, eLock); } /* ** This function should be called when an error occurs within the pager ** code. The first argument is a pointer to the pager structure, the ** second the error-code about to be returned by a pager API function. ** The value returned is a copy of the second argument to this function. ** ** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT, or SQLITE_FULL | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 | static int osUnlock(sqlite3_file *pFd, int eLock){ if( !pFd->pMethods ){ return SQLITE_OK; } return sqlite3OsUnlock(pFd, eLock); } /* ** This function determines whether or not the atomic-write optimization ** can be used with this pager. The optimization can be used if: ** ** (a) the value returned by OsDeviceCharacteristics() indicates that ** a database page may be written atomically, and ** (b) the value returned by OsSectorSize() is less than or equal ** to the page size. ** ** If the optimization cannot be used, 0 is returned. If it can be used, ** then the value returned is the size of the journal file when it ** contains rollback data for exactly one page. */ #ifdef SQLITE_ENABLE_ATOMIC_WRITE static int jrnlBufferSize(Pager *pPager){ int dc; /* Device characteristics */ int nSector; /* Sector size */ int nPage; /* Page size */ sqlite3_file *fd = pPager->fd; if( fd->pMethods ){ dc = sqlite3OsDeviceCharacteristics(fd); nSector = sqlite3OsSectorSize(fd); nPage = pPager->pageSize; } assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); if( !fd->pMethods || (dc&(SQLITE_IOCAP_ATOMIC|(nPage<<8))&&nSector<=nPage) ){ return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager); } return 0; } #endif /* ** This function should be called when an error occurs within the pager ** code. The first argument is a pointer to the pager structure, the ** second the error-code about to be returned by a pager API function. ** The value returned is a copy of the second argument to this function. ** ** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT, or SQLITE_FULL |
︙ | ︙ | |||
1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 | int rc = SQLITE_OK; int i; int tempFile = 0; int memDb = 0; int readOnly = 0; int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; int noReadlock = (flags & PAGER_NO_READLOCK)!=0; /* The default return is a NULL pointer */ *ppPager = 0; /* Allocate memory for the pager structure */ pPager = sqlite3MallocZero( sizeof(*pPager) + /* Pager structure */ | > > | | | | | 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 | int rc = SQLITE_OK; int i; int tempFile = 0; int memDb = 0; int readOnly = 0; int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; int noReadlock = (flags & PAGER_NO_READLOCK)!=0; int journalFileSize = sqlite3JournalSize(pVfs); /* The default return is a NULL pointer */ *ppPager = 0; /* Allocate memory for the pager structure */ pPager = sqlite3MallocZero( sizeof(*pPager) + /* Pager structure */ journalFileSize + /* The journal file structure */ pVfs->szOsFile * 2 + /* The db and stmt journal files */ pVfs->mxPathname * 3 + 30 /* zFilename, zDirectory, zJournal */ ); if( !pPager ){ return SQLITE_NOMEM; } pPtr = (u8 *)&pPager[1]; pPager->fd = (sqlite3_file*)&pPtr[pVfs->szOsFile*0]; pPager->stfd = (sqlite3_file*)&pPtr[pVfs->szOsFile*1]; pPager->jfd = (sqlite3_file*)&pPtr[pVfs->szOsFile*2]; pPager->zFilename = (char*)&pPtr[pVfs->szOsFile*2+journalFileSize]; pPager->zDirectory = &pPager->zFilename[pVfs->mxPathname]; pPager->zJournal = &pPager->zDirectory[pVfs->mxPathname]; pPager->pVfs = pVfs; /* Open the pager file and set zFullPathname to point at malloc()ed ** memory containing the complete filename (i.e. including the directory). */ |
︙ | ︙ | |||
1867 1868 1869 1870 1871 1872 1873 | } } }else{ /* If a temporary file is requested, it is not opened immediately. ** In this case we accept the default page size and delay actually ** opening the file until the first call to OsWrite(). */ | < | 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 | } } }else{ /* If a temporary file is requested, it is not opened immediately. ** In this case we accept the default page size and delay actually ** opening the file until the first call to OsWrite(). */ tempFile = 1; pPager->state = PAGER_EXCLUSIVE; } if( pPager && rc==SQLITE_OK ){ pPager->pTmpSpace = (char *)sqlite3_malloc(SQLITE_DEFAULT_PAGE_SIZE); } |
︙ | ︙ | |||
2994 2995 2996 2997 2998 2999 3000 | ** a read/write file handle. */ rc = SQLITE_BUSY; if( sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){ int fout = 0; int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; assert( !pPager->tempFile ); | | | 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 | ** a read/write file handle. */ rc = SQLITE_BUSY; if( sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){ int fout = 0; int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; assert( !pPager->tempFile ); rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags,&fout); assert( rc!=SQLITE_OK || pPager->jfd->pMethods ); if( fout&SQLITE_OPEN_READONLY ){ rc = SQLITE_BUSY; sqlite3OsClose(pPager->jfd); } } if( rc!=SQLITE_OK ){ |
︙ | ︙ | |||
3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 | } if( pPager->tempFile ){ flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL); }else{ flags |= (SQLITE_OPEN_MAIN_JOURNAL); } rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0); assert( rc!=SQLITE_OK || pPager->jfd->pMethods ); pPager->journalOff = 0; pPager->setMaster = 0; pPager->journalHdr = 0; if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ){ sqlite3OsDelete(pVfs, pPager->zJournal, 0); | > > > > > > | 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 | } if( pPager->tempFile ){ flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL); }else{ flags |= (SQLITE_OPEN_MAIN_JOURNAL); } #ifdef SQLITE_ENABLE_ATOMIC_WRITE rc = sqlite3JournalOpen( pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager) ); #else rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0); #endif assert( rc!=SQLITE_OK || pPager->jfd->pMethods ); pPager->journalOff = 0; pPager->setMaster = 0; pPager->journalHdr = 0; if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ){ sqlite3OsDelete(pVfs, pPager->zJournal, 0); |
︙ | ︙ | |||
4006 4007 4008 4009 4010 4011 4012 | } /* ** This routine is called to increment the database file change-counter, ** stored at byte 24 of the pager file. */ | | | > > | | | > > > > > > > | | 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 | } /* ** This routine is called to increment the database file change-counter, ** stored at byte 24 of the pager file. */ static int pager_incr_changecounter(Pager *pPager, int isDirect){ PgHdr *pPgHdr; u32 change_counter; int rc = SQLITE_OK; if( !pPager->changeCountDone ){ /* Open page 1 of the file for writing. */ rc = sqlite3PagerGet(pPager, 1, &pPgHdr); if( rc!=SQLITE_OK ) return rc; if( !isDirect ){ rc = sqlite3PagerWrite(pPgHdr); if( rc!=SQLITE_OK ) return rc; } /* Increment the value just read and write it back to byte 24. */ change_counter = sqlite3Get4byte((u8*)pPager->dbFileVers); change_counter++; put32bits(((char*)PGHDR_TO_DATA(pPgHdr))+24, change_counter); if( isDirect && pPager->fd->pMethods ){ const void *zBuf = PGHDR_TO_DATA(pPgHdr); rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0); } /* Release the page reference. */ sqlite3PagerUnref(pPgHdr); pPager->changeCountDone = 1; } return rc; } /* ** Sync the database file for the pager pPager. zMaster points to the name ** of a master journal file that should be written into the individual ** journal file. zMaster may be NULL, which is interpreted as no master ** journal (a single database transaction). |
︙ | ︙ | |||
4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 | /* If this is an in-memory db, or no pages have been written to, or this ** function has already been called, it is a no-op. */ if( pPager->state!=PAGER_SYNCED && !MEMDB && pPager->dirtyCache ){ PgHdr *pPg; assert( pPager->journalOpen ); /* If a master journal file name has already been written to the ** journal file, then no sync is required. This happens when it is ** written, then the process fails to upgrade from a RESERVED to an ** EXCLUSIVE lock. The next time the process tries to commit the ** transaction the m-j name will have already been written. */ if( !pPager->setMaster ){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 | /* If this is an in-memory db, or no pages have been written to, or this ** function has already been called, it is a no-op. */ if( pPager->state!=PAGER_SYNCED && !MEMDB && pPager->dirtyCache ){ PgHdr *pPg; assert( pPager->journalOpen ); #ifdef SQLITE_ENABLE_ATOMIC_WRITE /* The atomic-write optimization can be used if all of the ** following are true: ** ** + The file-system supports the atomic-write property for ** blocks of size page-size, and ** + This commit is not part of a multi-file transaction, and ** + Exactly one page has been modified and store in the journal file. ** ** If the optimization can be used, then the journal file will never ** be created for this transaction. */ if( !zMaster && pPager->journalOff==jrnlBufferSize(pPager) && nTrunc==0 && (0==pPager->pDirty || 0==pPager->pDirty->pDirty) ){ /* Update the nRec field in the journal file. */ int offset = pPager->journalHdr + sizeof(aJournalMagic); assert(pPager->nRec==1); rc = write32bits(pPager->jfd, offset, pPager->nRec); /* Update the db file change counter. The following call will modify ** the in-memory representation of page 1 to include the updated ** change counter and then write page 1 directly to the database ** file. Because of the atomic-write property of the host file-system, ** this is safe. */ rc = pager_incr_changecounter(pPager, 1); }else #endif /* If a master journal file name has already been written to the ** journal file, then no sync is required. This happens when it is ** written, then the process fails to upgrade from a RESERVED to an ** EXCLUSIVE lock. The next time the process tries to commit the ** transaction the m-j name will have already been written. */ if( !pPager->setMaster ){ rc = pager_incr_changecounter(pPager, 0); if( rc!=SQLITE_OK ) goto sync_exit; #ifndef SQLITE_OMIT_AUTOVACUUM if( nTrunc!=0 ){ /* If this transaction has made the database smaller, then all pages ** being discarded by the truncation must be written to the journal ** file. */ |
︙ | ︙ | |||
4091 4092 4093 4094 4095 4096 4097 | } } } #endif rc = writeMasterJournal(pPager, zMaster); if( rc!=SQLITE_OK ) goto sync_exit; rc = syncJournal(pPager); | < > | 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 | } } } #endif rc = writeMasterJournal(pPager, zMaster); if( rc!=SQLITE_OK ) goto sync_exit; rc = syncJournal(pPager); } if( rc!=SQLITE_OK ) goto sync_exit; #ifndef SQLITE_OMIT_AUTOVACUUM if( nTrunc!=0 ){ rc = sqlite3PagerTruncate(pPager, nTrunc); if( rc!=SQLITE_OK ) goto sync_exit; } #endif |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.596 2007/08/22 11:22:04 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ #include "sqliteLimit.h" #if defined(SQLITE_TCL) || defined(TCLSH) |
︙ | ︙ | |||
1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 | int sqlite3VtabCallDestroy(sqlite3*, int, const char *); int sqlite3VtabBegin(sqlite3 *, sqlite3_vtab *); FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**); int sqlite3Reprepare(Vdbe*); void sqlite3ExprListCheckLength(Parse*, ExprList*, int, const char*); CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); #if SQLITE_MAX_EXPR_DEPTH>0 void sqlite3ExprSetHeight(Expr *); int sqlite3SelectExprHeight(Select *); #else #define sqlite3ExprSetHeight(x) #endif | > > > > > > > | 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 | int sqlite3VtabCallDestroy(sqlite3*, int, const char *); int sqlite3VtabBegin(sqlite3 *, sqlite3_vtab *); FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**); int sqlite3Reprepare(Vdbe*); void sqlite3ExprListCheckLength(Parse*, ExprList*, int, const char*); CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); #ifdef SQLITE_ENABLE_ATOMIC_WRITE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); int sqlite3JournalSize(sqlite3_vfs *); #else #define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile) #endif #if SQLITE_MAX_EXPR_DEPTH>0 void sqlite3ExprSetHeight(Expr *); int sqlite3SelectExprHeight(Select *); #else #define sqlite3ExprSetHeight(x) #endif |
︙ | ︙ |