diff options
author | dan <dan@noemail.net> | 2020-07-13 18:04:27 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2020-07-13 18:04:27 +0000 |
commit | a7f82d9f47ca75a2f47dc14f8a8deb6730d718d0 (patch) | |
tree | e2000d1d8b1b14297c1a8790c65dd90c4a20e2b9 /src/pager.c | |
parent | 7465787b97a0a09841e343630a07ba80f1399e4a (diff) | |
parent | 5b107654e965973e68c88f90a09a3cc53bac9d8b (diff) | |
download | sqlite-a7f82d9f47ca75a2f47dc14f8a8deb6730d718d0.tar.gz sqlite-a7f82d9f47ca75a2f47dc14f8a8deb6730d718d0.zip |
Merge latest trunk changes with this branch.
FossilOrigin-Name: 5ee3c27e20d12a126fb773b428bb864102b949a5b26a8d5c523753dcedf4be10
Diffstat (limited to 'src/pager.c')
-rw-r--r-- | src/pager.c | 379 |
1 files changed, 197 insertions, 182 deletions
diff --git a/src/pager.c b/src/pager.c index 0d08a2dfa..729174a2a 100644 --- a/src/pager.c +++ b/src/pager.c @@ -70,8 +70,8 @@ ** (5) All writes to the database file are synced prior to the rollback journal ** being deleted, truncated, or zeroed. ** -** (6) If a master journal file is used, then all writes to the database file -** are synced prior to the master journal being deleted. +** (6) If a super-journal file is used, then all writes to the database file +** are synced prior to the super-journal being deleted. ** ** Definition: Two databases (or the same database at two points it time) ** are said to be "logically equivalent" if they give the same answer to @@ -488,29 +488,29 @@ struct PagerSavepoint { ** need only update the change-counter once, for the first transaction ** committed. ** -** setMaster +** setSuper ** ** When PagerCommitPhaseOne() is called to commit a transaction, it may -** (or may not) specify a master-journal name to be written into the +** (or may not) specify a super-journal name to be written into the ** journal file before it is synced to disk. ** -** Whether or not a journal file contains a master-journal pointer affects +** Whether or not a journal file contains a super-journal pointer affects ** the way in which the journal file is finalized after the transaction is ** committed or rolled back when running in "journal_mode=PERSIST" mode. -** If a journal file does not contain a master-journal pointer, it is +** If a journal file does not contain a super-journal pointer, it is ** finalized by overwriting the first journal header with zeroes. If -** it does contain a master-journal pointer the journal file is finalized +** it does contain a super-journal pointer the journal file is finalized ** by truncating it to zero bytes, just as if the connection were ** running in "journal_mode=truncate" mode. ** -** Journal files that contain master journal pointers cannot be finalized +** Journal files that contain super-journal pointers cannot be finalized ** simply by overwriting the first journal-header with zeroes, as the -** master journal pointer could interfere with hot-journal rollback of any +** super-journal pointer could interfere with hot-journal rollback of any ** subsequently interrupted transaction that reuses the journal file. ** ** The flag is cleared as soon as the journal file is finalized (either ** by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the -** journal file from being successfully finalized, the setMaster flag +** journal file from being successfully finalized, the setSuper flag ** is cleared anyway (and the pager will move to ERROR state). ** ** doNotSpill @@ -642,7 +642,7 @@ struct Pager { u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */ u8 eLock; /* Current lock held on database file */ u8 changeCountDone; /* Set after incrementing the change-counter */ - u8 setMaster; /* True if a m-j name has been written to jrnl */ + u8 setSuper; /* Super-jrnl name is written into jrnl */ u8 doNotSpill; /* Do not spill the cache when non-zero */ u8 subjInMemory; /* True to use in-memory sub-journals */ u8 bUseFetch; /* True to use xFetch() */ @@ -920,7 +920,7 @@ static int assert_pager_state(Pager *p){ assert( pPager->dbSize==pPager->dbOrigSize ); assert( pPager->dbOrigSize==pPager->dbFileSize ); assert( pPager->dbOrigSize==pPager->dbHintSize ); - assert( pPager->setMaster==0 ); + assert( pPager->setSuper==0 ); break; case PAGER_WRITER_CACHEMOD: @@ -1274,66 +1274,66 @@ static void checkPage(PgHdr *pPg){ /* ** When this is called the journal file for pager pPager must be open. -** This function attempts to read a master journal file name from the +** This function attempts to read a super-journal file name from the ** end of the file and, if successful, copies it into memory supplied -** by the caller. See comments above writeMasterJournal() for the format -** used to store a master journal file name at the end of a journal file. +** by the caller. See comments above writeSuperJournal() for the format +** used to store a super-journal file name at the end of a journal file. ** -** zMaster must point to a buffer of at least nMaster bytes allocated by +** zSuper must point to a buffer of at least nSuper bytes allocated by ** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is -** enough space to write the master journal name). If the master journal -** name in the journal is longer than nMaster bytes (including a -** nul-terminator), then this is handled as if no master journal name +** enough space to write the super-journal name). If the super-journal +** name in the journal is longer than nSuper bytes (including a +** nul-terminator), then this is handled as if no super-journal name ** were present in the journal. ** -** If a master journal file name is present at the end of the journal -** file, then it is copied into the buffer pointed to by zMaster. A -** nul-terminator byte is appended to the buffer following the master -** journal file name. +** If a super-journal file name is present at the end of the journal +** file, then it is copied into the buffer pointed to by zSuper. A +** nul-terminator byte is appended to the buffer following the +** super-journal file name. ** -** If it is determined that no master journal file name is present -** zMaster[0] is set to 0 and SQLITE_OK returned. +** If it is determined that no super-journal file name is present +** zSuper[0] is set to 0 and SQLITE_OK returned. ** ** If an error occurs while reading from the journal file, an SQLite ** error code is returned. */ -static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){ +static int readSuperJournal(sqlite3_file *pJrnl, char *zSuper, u32 nSuper){ int rc; /* Return code */ - u32 len; /* Length in bytes of master journal name */ + u32 len; /* Length in bytes of super-journal name */ i64 szJ; /* Total size in bytes of journal file pJrnl */ u32 cksum; /* MJ checksum value read from journal */ u32 u; /* Unsigned loop counter */ unsigned char aMagic[8]; /* A buffer to hold the magic header */ - zMaster[0] = '\0'; + zSuper[0] = '\0'; if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ)) || szJ<16 || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len)) - || len>=nMaster + || len>=nSuper || len>szJ-16 || len==0 || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum)) || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) || memcmp(aMagic, aJournalMagic, 8) - || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len)) + || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zSuper, len, szJ-16-len)) ){ return rc; } - /* See if the checksum matches the master journal name */ + /* See if the checksum matches the super-journal name */ for(u=0; u<len; u++){ - cksum -= zMaster[u]; + cksum -= zSuper[u]; } if( cksum ){ /* If the checksum doesn't add up, then one or more of the disk sectors - ** containing the master journal filename is corrupted. This means + ** containing the super-journal filename is corrupted. This means ** definitely roll back, so just return SQLITE_OK and report a (nul) - ** master-journal filename. + ** super-journal filename. */ len = 0; } - zMaster[len] = '\0'; - zMaster[len+1] = '\0'; + zSuper[len] = '\0'; + zSuper[len+1] = '\0'; return SQLITE_OK; } @@ -1661,50 +1661,50 @@ static int readJournalHdr( /* -** Write the supplied master journal name into the journal file for pager -** pPager at the current location. The master journal name must be the last +** Write the supplied super-journal name into the journal file for pager +** pPager at the current location. The super-journal name must be the last ** thing written to a journal file. If the pager is in full-sync mode, the ** journal file descriptor is advanced to the next sector boundary before ** anything is written. The format is: ** ** + 4 bytes: PAGER_MJ_PGNO. -** + N bytes: Master journal filename in utf-8. -** + 4 bytes: N (length of master journal name in bytes, no nul-terminator). -** + 4 bytes: Master journal name checksum. +** + N bytes: super-journal filename in utf-8. +** + 4 bytes: N (length of super-journal name in bytes, no nul-terminator). +** + 4 bytes: super-journal name checksum. ** + 8 bytes: aJournalMagic[]. ** -** The master journal page checksum is the sum of the bytes in the master -** journal name, where each byte is interpreted as a signed 8-bit integer. +** The super-journal page checksum is the sum of the bytes in thesuper-journal +** name, where each byte is interpreted as a signed 8-bit integer. ** -** If zMaster is a NULL pointer (occurs for a single database transaction), +** If zSuper is a NULL pointer (occurs for a single database transaction), ** this call is a no-op. */ -static int writeMasterJournal(Pager *pPager, const char *zMaster){ +static int writeSuperJournal(Pager *pPager, const char *zSuper){ int rc; /* Return code */ - int nMaster; /* Length of string zMaster */ + int nSuper; /* Length of string zSuper */ i64 iHdrOff; /* Offset of header in journal file */ i64 jrnlSize; /* Size of journal file on disk */ - u32 cksum = 0; /* Checksum of string zMaster */ + u32 cksum = 0; /* Checksum of string zSuper */ - assert( pPager->setMaster==0 ); + assert( pPager->setSuper==0 ); assert( !pagerUseWal(pPager) ); - if( !zMaster + if( !zSuper || pPager->journalMode==PAGER_JOURNALMODE_MEMORY || !isOpen(pPager->jfd) ){ return SQLITE_OK; } - pPager->setMaster = 1; + pPager->setSuper = 1; assert( pPager->journalHdr <= pPager->journalOff ); - /* Calculate the length in bytes and the checksum of zMaster */ - for(nMaster=0; zMaster[nMaster]; nMaster++){ - cksum += zMaster[nMaster]; + /* Calculate the length in bytes and the checksum of zSuper */ + for(nSuper=0; zSuper[nSuper]; nSuper++){ + cksum += zSuper[nSuper]; } /* If in full-sync mode, advance to the next disk sector before writing - ** the master journal name. This is in case the previous page written to + ** the super-journal name. This is in case the previous page written to ** the journal has already been synced. */ if( pPager->fullSync ){ @@ -1712,25 +1712,25 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){ } iHdrOff = pPager->journalOff; - /* Write the master journal data to the end of the journal file. If + /* Write the super-journal data to the end of the journal file. If ** an error occurs, return the error code to the caller. */ if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager)))) - || (0 != (rc = sqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4))) - || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster))) - || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum))) + || (0 != (rc = sqlite3OsWrite(pPager->jfd, zSuper, nSuper, iHdrOff+4))) + || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper, nSuper))) + || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper+4, cksum))) || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, - iHdrOff+4+nMaster+8))) + iHdrOff+4+nSuper+8))) ){ return rc; } - pPager->journalOff += (nMaster+20); + pPager->journalOff += (nSuper+20); /* If the pager is in peristent-journal mode, then the physical - ** journal-file may extend past the end of the master-journal name + ** journal-file may extend past the end of the super-journal name ** and 8 bytes of magic data just written to the file. This is ** dangerous because the code to rollback a hot-journal file - ** will not be able to find the master-journal name to determine + ** will not be able to find the super-journal name to determine ** whether or not the journal is hot. ** ** Easiest thing to do in this scenario is to truncate the journal @@ -1891,7 +1891,7 @@ static void pager_unlock(Pager *pPager){ pPager->journalOff = 0; pPager->journalHdr = 0; - pPager->setMaster = 0; + pPager->setSuper = 0; } /* @@ -2007,7 +2007,7 @@ static int pagerFlushOnCommit(Pager *pPager, int bCommit){ ** to the first error encountered (the journal finalization one) is ** returned. */ -static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ +static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){ int rc = SQLITE_OK; /* Error code from journal finalization operation */ int rc2 = SQLITE_OK; /* Error code from db file unlock operation */ @@ -2059,7 +2059,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL) ){ - rc = zeroJournalHdr(pPager, hasMaster||pPager->tempFile); + rc = zeroJournalHdr(pPager, hasSuper||pPager->tempFile); pPager->journalOff = 0; }else{ /* This branch may be executed with Pager.journalMode==MEMORY if @@ -2132,7 +2132,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ rc2 = pagerUnlockDb(pPager, SHARED_LOCK); } pPager->eState = PAGER_READER; - pPager->setMaster = 0; + pPager->setSuper = 0; return (rc==SQLITE_OK?rc2:rc); } @@ -2440,36 +2440,36 @@ static int pager_playback_one_page( } /* -** Parameter zMaster is the name of a master journal file. A single journal -** file that referred to the master journal file has just been rolled back. -** This routine checks if it is possible to delete the master journal file, +** Parameter zSuper is the name of a super-journal file. A single journal +** file that referred to the super-journal file has just been rolled back. +** This routine checks if it is possible to delete the super-journal file, ** and does so if it is. ** -** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not +** Argument zSuper may point to Pager.pTmpSpace. So that buffer is not ** available for use within this function. ** -** When a master journal file is created, it is populated with the names +** When a super-journal file is created, it is populated with the names ** of all of its child journals, one after another, formatted as utf-8 ** encoded text. The end of each child journal file is marked with a -** nul-terminator byte (0x00). i.e. the entire contents of a master journal +** nul-terminator byte (0x00). i.e. the entire contents of a super-journal ** file for a transaction involving two databases might be: ** ** "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00" ** -** A master journal file may only be deleted once all of its child +** A super-journal file may only be deleted once all of its child ** journals have been rolled back. ** -** This function reads the contents of the master-journal file into +** This function reads the contents of the super-journal file into ** memory and loops through each of the child journal names. For ** each child journal, it checks if: ** ** * if the child journal exists, and if so -** * if the child journal contains a reference to master journal -** file zMaster +** * if the child journal contains a reference to super-journal +** file zSuper ** ** If a child journal can be found that matches both of the criteria ** above, this function returns without doing anything. Otherwise, if -** no such child journal can be found, file zMaster is deleted from +** no such child journal can be found, file zSuper is deleted from ** the file-system using sqlite3OsDelete(). ** ** If an IO error within this function, an error code is returned. This @@ -2478,99 +2478,99 @@ static int pager_playback_one_page( ** occur, SQLITE_OK is returned. ** ** TODO: This function allocates a single block of memory to load -** the entire contents of the master journal file. This could be +** the entire contents of the super-journal file. This could be ** a couple of kilobytes or so - potentially larger than the page ** size. */ -static int pager_delmaster(Pager *pPager, const char *zMaster){ +static int pager_delsuper(Pager *pPager, const char *zSuper){ sqlite3_vfs *pVfs = pPager->pVfs; int rc; /* Return code */ - sqlite3_file *pMaster; /* Malloc'd master-journal file descriptor */ + sqlite3_file *pSuper; /* Malloc'd super-journal file descriptor */ sqlite3_file *pJournal; /* Malloc'd child-journal file descriptor */ - char *zMasterJournal = 0; /* Contents of master journal file */ - i64 nMasterJournal; /* Size of master journal file */ + char *zSuperJournal = 0; /* Contents of super-journal file */ + i64 nSuperJournal; /* Size of super-journal file */ char *zJournal; /* Pointer to one journal within MJ file */ - char *zMasterPtr; /* Space to hold MJ filename from a journal file */ - int nMasterPtr; /* Amount of space allocated to zMasterPtr[] */ + char *zSuperPtr; /* Space to hold super-journal filename */ + int nSuperPtr; /* Amount of space allocated to zSuperPtr[] */ - /* Allocate space for both the pJournal and pMaster file descriptors. - ** If successful, open the master journal file for reading. + /* Allocate space for both the pJournal and pSuper file descriptors. + ** If successful, open the super-journal file for reading. */ - pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2); - pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile); - if( !pMaster ){ + pSuper = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2); + pJournal = (sqlite3_file *)(((u8 *)pSuper) + pVfs->szOsFile); + if( !pSuper ){ rc = SQLITE_NOMEM_BKPT; }else{ - const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL); - rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0); + const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_SUPER_JOURNAL); + rc = sqlite3OsOpen(pVfs, zSuper, pSuper, flags, 0); } - if( rc!=SQLITE_OK ) goto delmaster_out; + if( rc!=SQLITE_OK ) goto delsuper_out; - /* Load the entire master journal file into space obtained from - ** sqlite3_malloc() and pointed to by zMasterJournal. Also obtain - ** sufficient space (in zMasterPtr) to hold the names of master - ** journal files extracted from regular rollback-journals. + /* Load the entire super-journal file into space obtained from + ** sqlite3_malloc() and pointed to by zSuperJournal. Also obtain + ** sufficient space (in zSuperPtr) to hold the names of super-journal + ** files extracted from regular rollback-journals. */ - rc = sqlite3OsFileSize(pMaster, &nMasterJournal); - if( rc!=SQLITE_OK ) goto delmaster_out; - nMasterPtr = pVfs->mxPathname+1; - zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 2); - if( !zMasterJournal ){ + rc = sqlite3OsFileSize(pSuper, &nSuperJournal); + if( rc!=SQLITE_OK ) goto delsuper_out; + nSuperPtr = pVfs->mxPathname+1; + zSuperJournal = sqlite3Malloc(nSuperJournal + nSuperPtr + 2); + if( !zSuperJournal ){ rc = SQLITE_NOMEM_BKPT; - goto delmaster_out; + goto delsuper_out; } - zMasterPtr = &zMasterJournal[nMasterJournal+2]; - rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0); - if( rc!=SQLITE_OK ) goto delmaster_out; - zMasterJournal[nMasterJournal] = 0; - zMasterJournal[nMasterJournal+1] = 0; + zSuperPtr = &zSuperJournal[nSuperJournal+2]; + rc = sqlite3OsRead(pSuper, zSuperJournal, (int)nSuperJournal, 0); + if( rc!=SQLITE_OK ) goto delsuper_out; + zSuperJournal[nSuperJournal] = 0; + zSuperJournal[nSuperJournal+1] = 0; - zJournal = zMasterJournal; - while( (zJournal-zMasterJournal)<nMasterJournal ){ + zJournal = zSuperJournal; + while( (zJournal-zSuperJournal)<nSuperJournal ){ int exists; rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists); if( rc!=SQLITE_OK ){ - goto delmaster_out; + goto delsuper_out; } if( exists ){ - /* One of the journals pointed to by the master journal exists. - ** Open it and check if it points at the master journal. If - ** so, return without deleting the master journal file. + /* One of the journals pointed to by the super-journal exists. + ** Open it and check if it points at the super-journal. If + ** so, return without deleting the super-journal file. ** NB: zJournal is really a MAIN_JOURNAL. But call it a - ** MASTER_JOURNAL here so that the VFS will not send the zJournal + ** SUPER_JOURNAL here so that the VFS will not send the zJournal ** name into sqlite3_database_file_object(). */ int c; - int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL); + int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_SUPER_JOURNAL); rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0); if( rc!=SQLITE_OK ){ - goto delmaster_out; + goto delsuper_out; } - rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr); + rc = readSuperJournal(pJournal, zSuperPtr, nSuperPtr); sqlite3OsClose(pJournal); if( rc!=SQLITE_OK ){ - goto delmaster_out; + goto delsuper_out; } - c = zMasterPtr[0]!=0 && strcmp(zMasterPtr, zMaster)==0; + c = zSuperPtr[0]!=0 && strcmp(zSuperPtr, zSuper)==0; if( c ){ - /* We have a match. Do not delete the master journal file. */ - goto delmaster_out; + /* We have a match. Do not delete the super-journal file. */ + goto delsuper_out; } } zJournal += (sqlite3Strlen30(zJournal)+1); } - sqlite3OsClose(pMaster); - rc = sqlite3OsDelete(pVfs, zMaster, 0); + sqlite3OsClose(pSuper); + rc = sqlite3OsDelete(pVfs, zSuper, 0); -delmaster_out: - sqlite3_free(zMasterJournal); - if( pMaster ){ - sqlite3OsClose(pMaster); +delsuper_out: + sqlite3_free(zSuperJournal); + if( pSuper ){ + sqlite3OsClose(pSuper); assert( !isOpen(pJournal) ); - sqlite3_free(pMaster); + sqlite3_free(pSuper); } return rc; } @@ -2648,7 +2648,7 @@ int sqlite3SectorSize(sqlite3_file *pFile){ ** pager based on the value returned by the xSectorSize method ** of the open database file. The sector size will be used ** to determine the size and alignment of journal header and -** master journal pointers within created journal files. +** super-journal pointers within created journal files. ** ** For temporary files the effective sector size is always 512 bytes. ** @@ -2747,7 +2747,7 @@ static int pager_playback(Pager *pPager, int isHot){ Pgno mxPg = 0; /* Size of the original file in pages */ int rc; /* Result code of a subroutine */ int res = 1; /* Value returned by sqlite3OsAccess() */ - char *zMaster = 0; /* Name of master journal file if any */ + char *zSuper = 0; /* Name of super-journal file if any */ int needPagerReset; /* True to reset page prior to first page rollback */ int nPlayback = 0; /* Total number of pages restored from journal */ u32 savedPageSize = pPager->pageSize; @@ -2761,8 +2761,8 @@ static int pager_playback(Pager *pPager, int isHot){ goto end_playback; } - /* Read the master journal name from the journal, if it is present. - ** If a master journal file name is specified, but the file is not + /* Read the super-journal name from the journal, if it is present. + ** If a super-journal file name is specified, but the file is not ** present on disk, then the journal is not hot and does not need to be ** played back. ** @@ -2772,12 +2772,12 @@ static int pager_playback(Pager *pPager, int isHot){ ** mxPathname is 512, which is the same as the minimum allowable value ** for pageSize. */ - zMaster = pPager->pTmpSpace; - rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1); - if( rc==SQLITE_OK && zMaster[0] ){ - rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res); + zSuper = pPager->pTmpSpace; + rc = readSuperJournal(pPager->jfd, zSuper, pPager->pVfs->mxPathname+1); + if( rc==SQLITE_OK && zSuper[0] ){ + rc = sqlite3OsAccess(pVfs, zSuper, SQLITE_ACCESS_EXISTS, &res); } - zMaster = 0; + zSuper = 0; if( rc!=SQLITE_OK || !res ){ goto end_playback; } @@ -2904,8 +2904,8 @@ end_playback: pPager->changeCountDone = pPager->tempFile; if( rc==SQLITE_OK ){ - zMaster = pPager->pTmpSpace; - rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1); + zSuper = pPager->pTmpSpace; + rc = readSuperJournal(pPager->jfd, zSuper, pPager->pVfs->mxPathname+1); testcase( rc!=SQLITE_OK ); } if( rc==SQLITE_OK @@ -2914,14 +2914,14 @@ end_playback: rc = sqlite3PagerSync(pPager, 0); } if( rc==SQLITE_OK ){ - rc = pager_end_transaction(pPager, zMaster[0]!='\0', 0); + rc = pager_end_transaction(pPager, zSuper[0]!='\0', 0); testcase( rc!=SQLITE_OK ); } - if( rc==SQLITE_OK && zMaster[0] && res ){ - /* If there was a master journal and this routine will return success, - ** see if it is possible to delete the master journal. + if( rc==SQLITE_OK && zSuper[0] && res ){ + /* If there was a super-journal and this routine will return success, + ** see if it is possible to delete the super-journal. */ - rc = pager_delmaster(pPager, zMaster); + rc = pager_delsuper(pPager, zSuper); testcase( rc!=SQLITE_OK ); } if( isHot && nPlayback ){ @@ -3300,7 +3300,7 @@ static int pagerOpenWalIfPresent(Pager *pPager){ /* ** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback -** the entire master journal file. The case pSavepoint==NULL occurs when +** the entire super-journal file. The case pSavepoint==NULL occurs when ** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction ** savepoint. ** @@ -5040,8 +5040,8 @@ sqlite3_file *sqlite3_database_file_object(const char *zName){ ** just deleted using OsDelete, *pExists is set to 0 and SQLITE_OK ** is returned. ** -** This routine does not check if there is a master journal filename -** at the end of the file. If there is, and that master journal file +** This routine does not check if there is a super-journal filename +** at the end of the file. If there is, and that super-journal file ** does not exist, then the journal file is not really hot. In this ** case this routine will return a false-positive. The pager_playback() ** routine will discover that the journal file is not really hot and @@ -5705,7 +5705,6 @@ void sqlite3PagerUnrefPageOne(DbPage *pPg){ assert( pPg->pgno==1 ); assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */ pPager = pPg->pPager; - sqlite3PagerResetLockTimeout(pPager); sqlite3PcacheRelease(pPg); pagerUnlockIfUnused(pPager); } @@ -5787,7 +5786,7 @@ static int pager_open_journal(Pager *pPager){ /* TODO: Check if all of these are really required. */ pPager->nRec = 0; pPager->journalOff = 0; - pPager->setMaster = 0; + pPager->setSuper = 0; pPager->journalHdr = 0; rc = writeJournalHdr(pPager); } @@ -6299,9 +6298,9 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ ** If successful, or if called on a pager for which it is a no-op, this ** function returns SQLITE_OK. Otherwise, an IO error code is returned. */ -int sqlite3PagerSync(Pager *pPager, const char *zMaster){ +int sqlite3PagerSync(Pager *pPager, const char *zSuper){ int rc = SQLITE_OK; - void *pArg = (void*)zMaster; + void *pArg = (void*)zSuper; rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg); if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; if( rc==SQLITE_OK && !pPager->noSync ){ @@ -6339,10 +6338,10 @@ int sqlite3PagerExclusiveLock(Pager *pPager){ } /* -** 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). +** Sync the database file for the pager pPager. zSuper points to the name +** of a super-journal file that should be written into the individual +** journal file. zSuper may be NULL, which is interpreted as no +** super-journal (a single database transaction). ** ** This routine ensures that: ** @@ -6354,9 +6353,9 @@ int sqlite3PagerExclusiveLock(Pager *pPager){ ** ** The only thing that remains to commit the transaction is to finalize ** (delete, truncate or zero the first part of) the journal file (or -** delete the master journal file if specified). +** delete the super-journal file if specified). ** -** Note that if zMaster==NULL, this does not overwrite a previous value +** Note that if zSuper==NULL, this does not overwrite a previous value ** passed to an sqlite3PagerCommitPhaseOne() call. ** ** If the final parameter - noSync - is true, then the database file itself @@ -6366,7 +6365,7 @@ int sqlite3PagerExclusiveLock(Pager *pPager){ */ int sqlite3PagerCommitPhaseOne( Pager *pPager, /* Pager object */ - const char *zMaster, /* If not NULL, the master journal name */ + const char *zSuper, /* If not NULL, the super-journal name */ int noSync /* True to omit the xSync on the db file */ ){ int rc = SQLITE_OK; /* Return code */ @@ -6384,8 +6383,8 @@ int sqlite3PagerCommitPhaseOne( /* Provide the ability to easily simulate an I/O error during testing */ if( sqlite3FaultSim(400) ) return SQLITE_IOERR; - PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", - pPager->zFilename, zMaster, pPager->dbSize)); + PAGERTRACE(("DATABASE SYNC: File=%s zSuper=%s nSize=%d\n", + pPager->zFilename, zSuper, pPager->dbSize)); /* If no database changes have been made, return early. */ if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK; @@ -6424,7 +6423,7 @@ int sqlite3PagerCommitPhaseOne( */ #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE sqlite3_file *fd = pPager->fd; - int bBatch = zMaster==0 /* An SQLITE_IOCAP_BATCH_ATOMIC commit */ + int bBatch = zSuper==0 /* An SQLITE_IOCAP_BATCH_ATOMIC commit */ && (sqlite3OsDeviceCharacteristics(fd) & SQLITE_IOCAP_BATCH_ATOMIC) && !pPager->noSync && sqlite3JournalIsInMemory(pPager->jfd); @@ -6462,7 +6461,7 @@ int sqlite3PagerCommitPhaseOne( || pPager->journalMode==PAGER_JOURNALMODE_OFF || pPager->journalMode==PAGER_JOURNALMODE_WAL ); - if( !zMaster && isOpen(pPager->jfd) + if( !zSuper && isOpen(pPager->jfd) && pPager->journalOff==jrnlBufferSize(pPager) && pPager->dbSize>=pPager->dbOrigSize && (!(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) @@ -6483,7 +6482,7 @@ int sqlite3PagerCommitPhaseOne( } #else /* SQLITE_ENABLE_ATOMIC_WRITE */ #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE - if( zMaster ){ + if( zSuper ){ rc = sqlite3JournalCreate(pPager->jfd); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; assert( bBatch==0 ); @@ -6493,11 +6492,11 @@ int sqlite3PagerCommitPhaseOne( #endif /* !SQLITE_ENABLE_ATOMIC_WRITE */ if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - /* Write the master journal name into the journal file. If a master - ** journal file name has already been written to the journal file, - ** or if zMaster is NULL (no master journal), then this call is a no-op. + /* Write the super-journal name into the journal file. If a + ** super-journal file name has already been written to the journal file, + ** or if zSuper is NULL (no super-journal), then this call is a no-op. */ - rc = writeMasterJournal(pPager, zMaster); + rc = writeSuperJournal(pPager, zSuper); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; /* Sync the journal file and write all dirty pages to the database. @@ -6565,7 +6564,7 @@ int sqlite3PagerCommitPhaseOne( /* Finally, sync the database file. */ if( !noSync ){ - rc = sqlite3PagerSync(pPager, zMaster); + rc = sqlite3PagerSync(pPager, zSuper); } IOTRACE(("DBSYNC %p\n", pPager)) } @@ -6630,7 +6629,7 @@ int sqlite3PagerCommitPhaseTwo(Pager *pPager){ } PAGERTRACE(("COMMIT %d\n", PAGERID(pPager))); - rc = pager_end_transaction(pPager, pPager->setMaster, 1); + rc = pager_end_transaction(pPager, pPager->setSuper, 1); return pager_error(pPager, rc); } @@ -6675,7 +6674,7 @@ int sqlite3PagerRollback(Pager *pPager){ if( pagerUseWal(pPager) ){ int rc2; rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1); - rc2 = pager_end_transaction(pPager, pPager->setMaster, 0); + rc2 = pager_end_transaction(pPager, pPager->setSuper, 0); if( rc==SQLITE_OK ) rc = rc2; }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){ int eState = pPager->eState; @@ -6998,16 +6997,6 @@ sqlite3_file *sqlite3PagerFile(Pager *pPager){ return pPager->fd; } -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -/* -** Reset the lock timeout for pager. -*/ -void sqlite3PagerResetLockTimeout(Pager *pPager){ - int x = 0; - sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x); -} -#endif - /* ** Return the file handle for the journal file (if it exists). ** This will be either the rollback journal or the WAL file. @@ -7421,7 +7410,6 @@ int sqlite3PagerCheckpoint( pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, pnLog, pnCkpt ); - sqlite3PagerResetLockTimeout(pPager); } return rc; } @@ -7586,7 +7574,31 @@ int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){ return rc; } +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +/* +** If pager pPager is a wal-mode database not in exclusive locking mode, +** invoke the sqlite3WalWriteLock() function on the associated Wal object +** with the same db and bLock parameters as were passed to this function. +** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise. +*/ +int sqlite3PagerWalWriteLock(Pager *pPager, int bLock){ + int rc = SQLITE_OK; + if( pagerUseWal(pPager) && pPager->exclusiveMode==0 ){ + rc = sqlite3WalWriteLock(pPager->pWal, bLock); + } + return rc; +} +/* +** Set the database handle used by the wal layer to determine if +** blocking locks are required. +*/ +void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ + if( pagerUseWal(pPager) ){ + sqlite3WalDb(pPager->pWal, db); + } +} +#endif #ifdef SQLITE_ENABLE_SNAPSHOT /* @@ -7606,7 +7618,10 @@ int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot){ ** read transaction is opened, attempt to read from the snapshot it ** identifies. If this is not a WAL database, return an error. */ -int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot){ +int sqlite3PagerSnapshotOpen( + Pager *pPager, + sqlite3_snapshot *pSnapshot +){ int rc = SQLITE_OK; if( pPager->pWal ){ sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot); |