/ Check-in [23c0e6c3]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge two wal leaves.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wal
Files: files | file ages | folders
SHA1: 23c0e6c3f333e878fe5a2ae5d61df0d765f437b4
User & Date: dan 2010-05-03 08:19:34
Context
2010-05-03
11:05
Add the "PRAGMA wal_autocheckpoint" command. Rename "PRAGMA checkpoint" to "PRAGMA wal_checkpoint". check-in: 714e5947 user: dan tags: wal
08:19
Merge two wal leaves. check-in: 23c0e6c3 user: dan tags: wal
08:04
Add the sqlite3_wal_checkpoint() and sqlite3_wal_autocheckpoint() APIs. check-in: 9803196d user: dan tags: wal
2010-05-01
20:17
Change the SHM interface so that it does not take the name of the shared object but rather the name of the WAL file and derives its own name from that. Remove the xShmDelete method from the VFS and replace it with a delete flag on xShmClose. check-in: 94dea5f9 user: drh tags: wal
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

  4919   4919       }else{
  4920   4920         pp = &p->pNext;
  4921   4921       }
  4922   4922     }
  4923   4923   }
  4924   4924   
  4925   4925   /*
  4926         -** Open a shared-memory area.  This implementation uses mmapped files.
         4926  +** Open a shared-memory area.  This particular implementation uses
         4927  +** mmapped files.
         4928  +**
         4929  +** zName is a filename used to identify the shared-memory area.  The
         4930  +** implementation does not (and perhaps should not) use this name
         4931  +** directly, but rather use it as a template for finding an appropriate
         4932  +** name for the shared-memory storage.  In this implementation, the
         4933  +** string "-index" is appended to zName and used as the name of the
         4934  +** mmapped file.
  4927   4935   **
  4928   4936   ** When opening a new shared-memory file, if no other instances of that
  4929   4937   ** file are currently open, in this process or in other processes, then
  4930   4938   ** the file must be truncated to zero length or have its header cleared.
  4931   4939   */
  4932   4940   static int unixShmOpen(
  4933   4941     sqlite3_vfs *pVfs,    /* The VFS */
  4934         -  const char *zName,    /* Name of file to mmap */
         4942  +  const char *zName,    /* Base name of file to mmap */
  4935   4943     sqlite3_shm **pShm    /* Write the unixShm object created here */
  4936   4944   ){
  4937   4945     struct unixShm *p = 0;             /* The connection to be opened */
  4938   4946     struct unixShmFile *pFile = 0;     /* The underlying mmapped file */
  4939   4947     int rc;                            /* Result code */
  4940   4948     struct unixFileId fid;             /* Unix file identifier */
         4949  +  struct unixShmFile *pNew;          /* Newly allocated pFile */
  4941   4950     struct stat sStat;                 /* Result from stat() an fstat() */
         4951  +  int nName;                         /* Size of zName in bytes */
  4942   4952   
  4943         -  /* Allocate space for the new sqlite3_shm object */
         4953  +  /* Allocate space for the new sqlite3_shm object.  Also speculatively
         4954  +  ** allocate space for a new unixShmFile and filename.
         4955  +  */
  4944   4956     p = sqlite3_malloc( sizeof(*p) );
  4945   4957     if( p==0 ) return SQLITE_NOMEM;
  4946   4958     memset(p, 0, sizeof(*p));
         4959  +  nName = strlen(zName);
         4960  +  pNew = sqlite3_malloc( sizeof(*pFile) + nName + 10 );
         4961  +  if( pNew==0 ){
         4962  +    rc = SQLITE_NOMEM;
         4963  +    goto shm_open_err;
         4964  +  }
         4965  +  memset(pNew, 0, sizeof(*pNew));
         4966  +  pNew->zFilename = (char*)&pNew[1];
         4967  +  sqlite3_snprintf(nName+10, pNew->zFilename, "%s-index", zName);
  4947   4968   
  4948   4969     /* Look to see if there is an existing unixShmFile that can be used.
  4949   4970     ** If no matching unixShmFile currently exists, create a new one.
  4950   4971     */
  4951   4972     unixEnterMutex();
  4952         -  rc = stat(zName, &sStat);
         4973  +  rc = stat(pNew->zFilename, &sStat);
  4953   4974     if( rc==0 ){
  4954   4975       memset(&fid, 0, sizeof(fid));
  4955   4976       fid.dev = sStat.st_dev;
  4956   4977       fid.ino = sStat.st_ino;
  4957   4978       for(pFile = unixShmFileList; pFile; pFile=pFile->pNext){
  4958   4979         if( memcmp(&pFile->fid, &fid, sizeof(fid))==0 ) break;
  4959   4980       }
  4960   4981     }
  4961         -  if( pFile==0 ){
  4962         -    int nName = strlen(zName);
  4963         -    pFile = sqlite3_malloc( sizeof(*pFile) + nName + 1 );
  4964         -    if( pFile==0 ){
  4965         -      rc = SQLITE_NOMEM;
  4966         -      goto shm_open_err;
  4967         -    }
  4968         -    memset(pFile, 0, sizeof(*pFile));
  4969         -    pFile->zFilename = (char*)&pFile[1];
  4970         -    memcpy(pFile->zFilename, zName, nName+1);
         4982  +  if( pFile ){
         4983  +    sqlite3_free(pNew);
         4984  +  }else{
         4985  +    pFile = pNew;
         4986  +    pNew = 0;
  4971   4987       pFile->h = -1;
  4972   4988       pFile->pNext = unixShmFileList;
  4973   4989       unixShmFileList = pFile;
  4974   4990   
  4975   4991       pFile->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
  4976   4992       if( pFile->mutex==0 ){
  4977   4993         rc = SQLITE_NOMEM;
................................................................................
  4979   4995       }
  4980   4996       pFile->mutexBuf = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
  4981   4997       if( pFile->mutexBuf==0 ){
  4982   4998         rc = SQLITE_NOMEM;
  4983   4999         goto shm_open_err;
  4984   5000       }
  4985   5001   
  4986         -    pFile->h = open(zName, O_RDWR|O_CREAT, 0664);
         5002  +    pFile->h = open(pFile->zFilename, O_RDWR|O_CREAT, 0664);
  4987   5003       if( pFile->h<0 ){
  4988   5004         rc = SQLITE_CANTOPEN_BKPT;
  4989   5005         goto shm_open_err;
  4990   5006       }
  4991   5007   
  4992   5008       rc = fstat(pFile->h, &sStat);
  4993   5009       if( rc ){
................................................................................
  5029   5045     return SQLITE_OK;
  5030   5046   
  5031   5047     /* Jump here on any error */
  5032   5048   shm_open_err:
  5033   5049     unixShmPurge();
  5034   5050     sqlite3_free(p);
  5035   5051     sqlite3_free(pFile);
         5052  +  sqlite3_free(pNew);
  5036   5053     *pShm = 0;
  5037   5054     unixLeaveMutex();
  5038   5055     return rc;
  5039   5056   }
  5040   5057   
  5041   5058   /*
  5042         -** Close a connectioon to shared-memory.
         5059  +** Close a connection to shared-memory.  Delete the underlying 
         5060  +** storage if deleteFlag is true.
  5043   5061   */
  5044         -static int unixShmClose(sqlite3_shm *pSharedMem){
         5062  +static int unixShmClose(sqlite3_shm *pSharedMem, int deleteFlag){
  5045   5063     unixShm *p;            /* The connection to be closed */
  5046   5064     unixShmFile *pFile;    /* The underlying shared-memory file */
  5047   5065     unixShm **pp;          /* For looping over sibling connections */
  5048   5066   
  5049   5067     if( pSharedMem==0 ) return SQLITE_OK;
  5050   5068     p = (struct unixShm*)pSharedMem;
  5051   5069     pFile = p->pFile;
................................................................................
  5065   5083   
  5066   5084     /* If pFile->nRef has reached 0, then close the underlying
  5067   5085     ** shared-memory file, too */
  5068   5086     unixEnterMutex();
  5069   5087     assert( pFile->nRef>0 );
  5070   5088     pFile->nRef--;
  5071   5089     if( pFile->nRef==0 ){
         5090  +    if( deleteFlag ) unlink(pFile->zFilename);
  5072   5091       unixShmPurge();
  5073   5092     }
  5074   5093     unixLeaveMutex();
  5075   5094   
  5076   5095     return SQLITE_OK;
  5077   5096   }
  5078   5097   
................................................................................
  5344   5363     sqlite3_mutex_leave(pFile->mutex);
  5345   5364     OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %s\n",
  5346   5365              p->id, getpid(), azLkName[p->lockState]));
  5347   5366     if( pGotLock ) *pGotLock = p->lockState;
  5348   5367     return rc;
  5349   5368   }
  5350   5369   
  5351         -/*
  5352         -** Delete a shared-memory segment from the system.
  5353         -*/
  5354         -static int unixShmDelete(sqlite3_vfs *pVfs, const char *zName){
  5355         -  return pVfs->xDelete(pVfs, zName, 0);
  5356         -}
  5357         -
  5358   5370   #else
  5359   5371   # define unixShmOpen    0
  5360   5372   # define unixShmSize    0
  5361   5373   # define unixShmGet     0
  5362   5374   # define unixShmRelease 0
  5363   5375   # define unixShmLock    0
  5364   5376   # define unixShmClose   0
  5365         -# define unixShmDelete  0
  5366   5377   #endif /* #ifndef SQLITE_OMIT_WAL */
  5367   5378   
  5368   5379   /*
  5369   5380   ************************ End of sqlite3_vfs methods ***************************
  5370   5381   ******************************************************************************/
  5371   5382   
  5372   5383   /******************************************************************************
................................................................................
  6583   6594       unixSleep,            /* xSleep */                      \
  6584   6595       unixCurrentTime,      /* xCurrentTime */                \
  6585   6596       unixGetLastError,     /* xGetLastError */               \
  6586   6597       unixShmOpen,          /* xShmOpen */                    \
  6587   6598       unixShmSize,          /* xShmSize */                    \
  6588   6599       unixShmGet,           /* xShmGet */                     \
  6589   6600       unixShmRelease,       /* xShmRelease */                 \
  6590         -    0,                    /* xShmPush */                    \
  6591         -    0,                    /* xShmPull */                    \
  6592   6601       unixShmLock,          /* xShmLock */                    \
  6593   6602       unixShmClose,         /* xShmClose */                   \
  6594         -    unixShmDelete,        /* xShmDelete */                  \
  6595   6603       0,                    /* xRename */                     \
  6596   6604       0,                    /* xCurrentTimeInt64 */           \
  6597   6605     }
  6598   6606   
  6599   6607     /*
  6600   6608     ** All default VFSes for unix are contained in the following array.
  6601   6609     **

Changes to src/sqlite.h.in.

   843    843     ** The methods above are in version 1 of the sqlite_vfs object
   844    844     ** definition.  Those that follow are added in version 2 or later
   845    845     */
   846    846     int (*xShmOpen)(sqlite3_vfs*, const char *zName, sqlite3_shm**);
   847    847     int (*xShmSize)(sqlite3_shm*, int reqSize, int *pNewSize);
   848    848     int (*xShmGet)(sqlite3_shm*, int reqMapSize, int *pMapSize, void**);
   849    849     int (*xShmRelease)(sqlite3_shm*);
   850         -  int (*xShmPush)(sqlite3_shm*);
   851         -  int (*xShmPull)(sqlite3_shm*);
   852    850     int (*xShmLock)(sqlite3_shm*, int desiredLock, int *gotLock);
   853         -  int (*xShmClose)(sqlite3_shm*);
   854         -  int (*xShmDelete)(sqlite3_vfs*, const char *zName);
          851  +  int (*xShmClose)(sqlite3_shm*, int deleteFlag);
   855    852     int (*xRename)(sqlite3_vfs*, const char *zOld, const char *zNew, int dirSync);
   856    853     int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
   857    854     /*
   858    855     ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
   859    856     ** New fields may be appended in figure versions.  The iVersion
   860    857     ** value will increment whenever this happens. 
   861    858     */

Changes to src/test_devsym.c.

    69     69   static int devsymCurrentTime(sqlite3_vfs*, double*);
    70     70   
    71     71   static int devsymShmOpen(sqlite3_vfs *, const char *, sqlite3_shm **);
    72     72   static int devsymShmSize(sqlite3_shm *, int , int *);
    73     73   static int devsymShmGet(sqlite3_shm *, int , int *, void **);
    74     74   static int devsymShmRelease(sqlite3_shm *);
    75     75   static int devsymShmLock(sqlite3_shm *, int , int *);
    76         -static int devsymShmClose(sqlite3_shm *);
    77         -static int devsymShmDelete(sqlite3_vfs *, const char *);
           76  +static int devsymShmClose(sqlite3_shm *, int);
    78     77   
    79     78   static sqlite3_vfs devsym_vfs = {
    80     79     2,                     /* iVersion */
    81     80     sizeof(devsym_file),      /* szOsFile */
    82     81     DEVSYM_MAX_PATHNAME,      /* mxPathname */
    83     82     0,                     /* pNext */
    84     83     DEVSYM_VFS_NAME,          /* zName */
................................................................................
   102    101     devsymSleep,              /* xSleep */
   103    102     devsymCurrentTime,        /* xCurrentTime */
   104    103     0,                        /* xGetLastError */
   105    104     devsymShmOpen,
   106    105     devsymShmSize,
   107    106     devsymShmGet,
   108    107     devsymShmRelease,
   109         -  0,
   110         -  0,
   111    108     devsymShmLock,
   112    109     devsymShmClose,
   113         -  devsymShmDelete,
   114    110     0,
   115    111     0,
   116    112   };
   117    113   
   118    114   static sqlite3_io_methods devsym_io_methods = {
   119    115     1,                            /* iVersion */
   120    116     devsymClose,                      /* xClose */
................................................................................
   374    370   }
   375    371   static int devsymShmRelease(sqlite3_shm *p){
   376    372     return g.pVfs->xShmRelease(p);
   377    373   }
   378    374   static int devsymShmLock(sqlite3_shm *p, int desiredLock, int *gotLock){
   379    375     return g.pVfs->xShmLock(p, desiredLock, gotLock);
   380    376   }
   381         -static int devsymShmClose(sqlite3_shm *p){
   382         -  return g.pVfs->xShmClose(p);
   383         -}
   384         -static int devsymShmDelete(sqlite3_vfs *pVfs, const char *zName){
   385         -  return g.pVfs->xShmDelete(g.pVfs, zName);
          377  +static int devsymShmClose(sqlite3_shm *p, int deleteFlag){
          378  +  return g.pVfs->xShmClose(p, deleteFlag);
   386    379   }
   387    380   
   388    381   /*
   389    382   ** This procedure registers the devsym vfs with SQLite. If the argument is
   390    383   ** true, the devsym vfs becomes the new default vfs. It is the only publicly
   391    384   ** available function in this file.
   392    385   */
................................................................................
   396    389       devsym_vfs.szOsFile += g.pVfs->szOsFile;
   397    390       devsym_vfs.xShmOpen = (g.pVfs->xShmOpen ? devsymShmOpen : 0);
   398    391       devsym_vfs.xShmSize = (g.pVfs->xShmSize ? devsymShmSize : 0);
   399    392       devsym_vfs.xShmGet = (g.pVfs->xShmGet ? devsymShmGet : 0);
   400    393       devsym_vfs.xShmRelease = (g.pVfs->xShmRelease ? devsymShmRelease : 0);
   401    394       devsym_vfs.xShmLock = (g.pVfs->xShmLock ? devsymShmLock : 0);
   402    395       devsym_vfs.xShmClose = (g.pVfs->xShmClose ? devsymShmClose : 0);
   403         -    devsym_vfs.xShmDelete = (g.pVfs->xShmDelete ? devsymShmDelete : 0);
   404    396       sqlite3_vfs_register(&devsym_vfs, 0);
   405    397     }
   406    398     if( iDeviceChar>=0 ){
   407    399       g.iDeviceChar = iDeviceChar;
   408    400     }else{
   409    401       g.iDeviceChar = 0;
   410    402     }

Changes to src/test_onefile.c.

   197    197       fsDlSym,                                    /* xDlSym */
   198    198       fsDlClose,                                  /* xDlClose */
   199    199       fsRandomness,                               /* xRandomness */
   200    200       fsSleep,                                    /* xSleep */
   201    201       fsCurrentTime,                              /* xCurrentTime */
   202    202       0,                                          /* xShmOpen */
   203    203       0,                                          /* xShmSize */
   204         -    0,                                          /* xShmPush */
   205         -    0,                                          /* xShmPull */
   206    204       0,                                          /* xShmLock */
   207    205       0,                                          /* xShmClose */
   208    206       0,                                          /* xShmDelete */
   209    207       0,                                          /* xRename */
   210    208       0                                           /* xCurrentTimeInt64 */
   211    209     }, 
   212    210     0,                                            /* pFileList */

Changes to src/wal.c.

   129    129     u32 iCallback;             /* Value to pass to log callback (or 0) */
   130    130     sqlite3_shm *pWIndex;      /* The open wal-index file */
   131    131     int szWIndex;              /* Size of the wal-index that is mapped in mem */
   132    132     u32 *pWiData;              /* Pointer to wal-index content in memory */
   133    133     u8 lockState;              /* SQLITE_SHM_xxxx constant showing lock state */
   134    134     u8 readerType;             /* SQLITE_SHM_READ or SQLITE_SHM_READ_FULL */
   135    135     WalIndexHdr hdr;           /* Wal-index for current snapshot */
          136  +  char *zName;               /* Name of underlying storage */
   136    137   };
   137    138   
   138    139   
   139    140   /*
   140    141   ** This structure is used to implement an iterator that iterates through
   141    142   ** all frames in the log in database page order. Where two or more frames
   142    143   ** correspond to the same database page, the iterator visits only the 
................................................................................
   586    587   
   587    588     assert( zDb );
   588    589     if( pVfs->xShmOpen==0 ) return SQLITE_CANTOPEN_BKPT;
   589    590   
   590    591     /* Allocate an instance of struct Wal to return. */
   591    592     *ppWal = 0;
   592    593     nWal = strlen(zDb);
   593         -  pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile + nWal+11);
          594  +  pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile + nWal+5);
   594    595     if( !pRet ) goto wal_open_out;
   595    596     pRet->pVfs = pVfs;
   596    597     pRet->pFd = (sqlite3_file *)&pRet[1];
   597         -  zWal = pVfs->szOsFile + (char*)pRet->pFd;
   598         -  sqlite3_snprintf(nWal+11, zWal, "%s-wal-index", zDb);
          598  +  pRet->zName = zWal = pVfs->szOsFile + (char*)pRet->pFd;
          599  +  sqlite3_snprintf(nWal+5, zWal, "%s-wal", zDb);
   599    600     rc = pVfs->xShmOpen(pVfs, zWal, &pRet->pWIndex);
   600    601     if( rc ) goto wal_open_out;
   601    602   
   602    603     /* Open file handle on the write-ahead log file. */
   603         -  zWal[nWal+4] = 0;
   604    604     flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_JOURNAL);
   605    605     rc = sqlite3OsOpen(pVfs, zWal, pRet->pFd, flags, &flags);
   606    606   
   607    607   wal_open_out:
   608    608     if( rc!=SQLITE_OK ){
   609    609       if( pRet ){
   610         -      pVfs->xShmClose(pRet->pWIndex);
          610  +      pVfs->xShmClose(pRet->pWIndex, 0);
   611    611         sqlite3OsClose(pRet->pFd);
   612    612         sqlite3_free(pRet);
   613    613       }
   614    614     }
   615    615     *ppWal = pRet;
   616    616     return rc;
   617    617   }
................................................................................
   801    801         rc = walCheckpoint(pWal, pFd, sync_flags, zBuf);
   802    802         if( rc==SQLITE_OK ){
   803    803           isDelete = 1;
   804    804         }
   805    805         walIndexUnmap(pWal);
   806    806       }
   807    807   
   808         -    pWal->pVfs->xShmClose(pWal->pWIndex);
          808  +    pWal->pVfs->xShmClose(pWal->pWIndex, isDelete);
   809    809       sqlite3OsClose(pWal->pFd);
   810    810       if( isDelete ){
   811         -      int nWal;
   812         -      char *zWal = &((char *)pWal->pFd)[pWal->pVfs->szOsFile];
   813         -      sqlite3OsDelete(pWal->pVfs, zWal, 0);
   814         -      nWal = sqlite3Strlen30(zWal);
   815         -      memcpy(&zWal[nWal], "-index", 7);
   816         -      pWal->pVfs->xShmDelete(pWal->pVfs, zWal);
          811  +      sqlite3OsDelete(pWal->pVfs, pWal->zName, 0);
   817    812       }
   818    813       sqlite3_free(pWal);
   819    814     }
   820    815     return rc;
   821    816   }
   822    817   
   823    818   /*