/ Check-in [dfe1dffa]
Login

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

Overview
Comment:Use heap instead of stack for large buffers in the pager. Fix for #2262. (CVS 3673)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: dfe1dffa4515ed6494055887d351863fe0cdb87f
User & Date: danielk1977 2007-03-06 13:46:00
Context
2007-03-06
15:53
Fixes to the overflow-chain optization of (3672). (CVS 3674) check-in: d6986d1e user: drh tags: trunk
13:46
Use heap instead of stack for large buffers in the pager. Fix for #2262. (CVS 3673) check-in: dfe1dffa user: danielk1977 tags: trunk
11:42
Do not read the last page of a overflow chain when deleting that chain. Just add the page to the freelist. This reduces I/O. (CVS 3672) check-in: 6db945f7 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/pager.c.

    14     14   ** The pager is used to access a database disk file.  It implements
    15     15   ** atomic commit and rollback through the use of a journal file that
    16     16   ** is separate from the database file.  The pager also implements file
    17     17   ** locking to prevent two processes from writing the same database
    18     18   ** file simultaneously, or one process from reading the database while
    19     19   ** another is writing.
    20     20   **
    21         -** @(#) $Id: pager.c,v 1.285 2007/03/04 13:15:28 drh Exp $
           21  +** @(#) $Id: pager.c,v 1.286 2007/03/06 13:46:00 danielk1977 Exp $
    22     22   */
    23     23   #ifndef SQLITE_OMIT_DISKIO
    24     24   #include "sqliteInt.h"
    25     25   #include "os.h"
    26     26   #include "pager.h"
    27     27   #include <assert.h>
    28     28   #include <string.h>
................................................................................
   280    280     void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
   281    281     void *pCodecArg;            /* First argument to xCodec() */
   282    282     int nHash;                  /* Size of the pager hash table */
   283    283     PgHdr **aHash;              /* Hash table to map page number to PgHdr */
   284    284   #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   285    285     Pager *pNext;               /* Linked list of pagers in this thread */
   286    286   #endif
          287  +  char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
   287    288   };
   288    289   
   289    290   /*
   290    291   ** If SQLITE_TEST is defined then increment the variable given in
   291    292   ** the argument
   292    293   */
   293    294   #ifdef SQLITE_TEST
................................................................................
   994    995   ** need to survive power failures.
   995    996   */
   996    997   static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
   997    998     int rc;
   998    999     PgHdr *pPg;                   /* An existing page in the cache */
   999   1000     Pgno pgno;                    /* The page number of a page in journal */
  1000   1001     u32 cksum;                    /* Checksum used for sanity checking */
  1001         -  u8 aData[SQLITE_MAX_PAGE_SIZE];  /* Temp storage for a page */
         1002  +  u8 *aData = (u8 *)pPager->pTmpSpace;   /* Temp storage for a page */
  1002   1003   
  1003   1004     /* useCksum should be true for the main journal and false for
  1004   1005     ** statement journals.  Verify that this is always the case
  1005   1006     */
  1006   1007     assert( jfd == (useCksum ? pPager->jfd : pPager->stfd) );
  1007         -
         1008  +  assert( aData );
  1008   1009   
  1009   1010     rc = read32bits(jfd, &pgno);
  1010   1011     if( rc!=SQLITE_OK ) return rc;
  1011         -  rc = sqlite3OsRead(jfd, &aData, pPager->pageSize);
         1012  +  rc = sqlite3OsRead(jfd, aData, pPager->pageSize);
  1012   1013     if( rc!=SQLITE_OK ) return rc;
  1013   1014     pPager->journalOff += pPager->pageSize + 4;
  1014   1015   
  1015   1016     /* Sanity checking on the page.  This is more important that I originally
  1016   1017     ** thought.  If a power failure occurs while the journal is being written,
  1017   1018     ** it could cause invalid data to be written into the journal.  We need to
  1018   1019     ** detect this invalid data (with high probability) and ignore it.
................................................................................
  1183   1184   ** cache content and the easiest way to do that is to reread the old content
  1184   1185   ** back from the disk.
  1185   1186   */
  1186   1187   static int pager_reload_cache(Pager *pPager){
  1187   1188     PgHdr *pPg;
  1188   1189     int rc = SQLITE_OK;
  1189   1190     for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
  1190         -    char zBuf[SQLITE_MAX_PAGE_SIZE];
         1191  +    char *zBuf = pPager->pTmpSpace;        /* Temp storage for one page */
  1191   1192       if( !pPg->dirty ) continue;
  1192   1193       if( (int)pPg->pgno <= pPager->origDbSize ){
  1193   1194         rc = sqlite3OsSeek(pPager->fd, pPager->pageSize*(i64)(pPg->pgno-1));
  1194   1195         if( rc==SQLITE_OK ){
  1195   1196           rc = sqlite3OsRead(pPager->fd, zBuf, pPager->pageSize);
  1196   1197         }
  1197   1198         TRACE3("REFETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
................................................................................
  1672   1673     /* Allocate the Pager structure. As part of the same allocation, allocate
  1673   1674     ** space for the full paths of the file, directory and journal 
  1674   1675     ** (Pager.zFilename, Pager.zDirectory and Pager.zJournal).
  1675   1676     */
  1676   1677     if( zFullPathname ){
  1677   1678       nameLen = strlen(zFullPathname);
  1678   1679       pPager = sqliteMalloc( sizeof(*pPager) + nameLen*3 + 30 );
         1680  +    if( pPager && rc==SQLITE_OK ){
         1681  +      pPager->pTmpSpace = (char *)sqliteMallocRaw(SQLITE_DEFAULT_PAGE_SIZE);
         1682  +    }
  1679   1683     }
         1684  +
  1680   1685   
  1681   1686     /* If an error occured in either of the blocks above, free the memory 
  1682   1687     ** pointed to by zFullPathname, free the Pager structure and close the 
  1683   1688     ** file. Since the pager is not allocated there is no need to set 
  1684   1689     ** any Pager.errMask variables.
  1685   1690     */
  1686         -  if( !pPager || !zFullPathname || rc!=SQLITE_OK ){
         1691  +  if( !pPager || !zFullPathname || !pPager->pTmpSpace || rc!=SQLITE_OK ){
  1687   1692       sqlite3OsClose(&fd);
  1688   1693       sqliteFree(zFullPathname);
  1689   1694       sqliteFree(pPager);
  1690   1695       return ((rc==SQLITE_OK)?SQLITE_NOMEM:rc);
  1691   1696     }
  1692   1697   
  1693   1698     TRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname);
................................................................................
  1776   1781   ** size is inappropriate, then an alternative page size is selected
  1777   1782   ** and returned.
  1778   1783   */
  1779   1784   int sqlite3pager_set_pagesize(Pager *pPager, int pageSize){
  1780   1785     assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE );
  1781   1786     if( !pPager->memDb ){
  1782   1787       pPager->pageSize = pageSize;
         1788  +    sqlite3ReallocOrFree((void **)&pPager->pTmpSpace, pageSize);
  1783   1789     }
  1784   1790     return pPager->pageSize;
  1785   1791   }
  1786   1792   
  1787   1793   /*
  1788   1794   ** The following set of routines are used to disable the simulated
  1789   1795   ** I/O error mechanism.  These routines are used to avoid simulated
................................................................................
  2111   2117     }else{
  2112   2118       Pager *pTmp;
  2113   2119       for(pTmp = pTsd->pPager; pTmp->pNext!=pPager; pTmp=pTmp->pNext){}
  2114   2120       pTmp->pNext = pPager->pNext;
  2115   2121     }
  2116   2122   #endif
  2117   2123     sqliteFree(pPager->aHash);
         2124  +  sqliteFree(pPager->pTmpSpace);
  2118   2125     sqliteFree(pPager);
  2119   2126     return SQLITE_OK;
  2120   2127   }
  2121   2128   
  2122   2129   /*
  2123   2130   ** Return the page number for the given page data.
  2124   2131   */