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

Overview
Comment:Fix a bug in merge-tree rollback operations.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 60c8db55530b9f6be2d363e505b01c5847c3f2ec
User & Date: dan 2014-01-26 17:13:07.585
Context
2014-02-03
07:40
Fix various problems causing block and page leaks during merge operations. check-in: aaac4355c7 user: dan tags: trunk
2014-01-26
17:13
Fix a bug in merge-tree rollback operations. check-in: 60c8db5553 user: dan tags: trunk
2014-01-25
15:14
Fix a problem with iterating in reverse order through the merge-tree. check-in: 6998cd99b8 user: dan tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/btInt.h.
283
284
285
286
287
288
289

290
291
292
293
294
295
296
int sqlite4BtLogPagecount(BtLog*);
u32 sqlite4BtLogCookie(BtLog*);
#endif
BtDbHdr *sqlite4BtLogDbhdr(BtLog*);

int sqlite4BtLogSetCookie(BtLog*, u32 iCookie);
int sqlite4BtLogDbhdrFlush(BtLog*);


/*
** End of bt_log.c interface.
*************************************************************************/

/*************************************************************************
** Interface to bt_lock.c functionality.







>







283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
int sqlite4BtLogPagecount(BtLog*);
u32 sqlite4BtLogCookie(BtLog*);
#endif
BtDbHdr *sqlite4BtLogDbhdr(BtLog*);

int sqlite4BtLogSetCookie(BtLog*, u32 iCookie);
int sqlite4BtLogDbhdrFlush(BtLog*);
void sqlite4BtLogReloadDbHdr(BtLog*);

/*
** End of bt_log.c interface.
*************************************************************************/

/*************************************************************************
** Interface to bt_lock.c functionality.
Changes to src/bt_log.c.
1959
1960
1961
1962
1963
1964
1965





1966
1967
1968
1969
1970
1971
1972
  return pLog->snapshot.dbhdr.iCookie;
}
#endif

BtDbHdr *sqlite4BtLogDbhdr(BtLog *pLog){
  return &pLog->snapshot.dbhdr;
}






int sqlite4BtLogDbhdrFlush(BtLog *pLog){
  BtPager *pPager = (BtPager *)(pLog->pLock);
  BtPage *pOne = 0;
  int rc;

  rc = sqlite4BtPageGet(pPager, 1, &pOne);







>
>
>
>
>







1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
  return pLog->snapshot.dbhdr.iCookie;
}
#endif

BtDbHdr *sqlite4BtLogDbhdr(BtLog *pLog){
  return &pLog->snapshot.dbhdr;
}

void sqlite4BtLogReloadDbHdr(BtLog *pLog){
  BtShm *pShm = btLogShm(pLog);
  memcpy(&pLog->snapshot, &pShm->hdr1, sizeof(BtShmHdr));
}

int sqlite4BtLogDbhdrFlush(BtLog *pLog){
  BtPager *pPager = (BtPager *)(pLog->pLock);
  BtPage *pOne = 0;
  int rc;

  rc = sqlite4BtPageGet(pPager, 1, &pOne);
Changes to src/bt_pager.c.
48
49
50
51
52
53
54

55
56
57
58
59
60
61
/*
** There is one object of this type for each open sub-transaction. Stored
** in the BtPager.aSavepoint[] array.
*/
struct BtSavepoint {
  int iLevel;                     /* Transaction level value (always >2) */
  BtSavepage *pSavepage;          /* First in linked list of saved data */

};

struct BtSavepage {
  BtPage *pPg;                    /* Pointer to page this object belongs to */
  u8 *aData;                      /* Saved data */
  BtSavepage *pNext;              /* Next saved page in the same savepoint */
  int iSavepoint;                 /* Transaction number of savepoint */







>







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/*
** There is one object of this type for each open sub-transaction. Stored
** in the BtPager.aSavepoint[] array.
*/
struct BtSavepoint {
  int iLevel;                     /* Transaction level value (always >2) */
  BtSavepage *pSavepage;          /* First in linked list of saved data */
  BtDbHdr hdr;                    /* Database header at start of savepoint */
};

struct BtSavepage {
  BtPage *pPg;                    /* Pointer to page this object belongs to */
  u8 *aData;                      /* Saved data */
  BtSavepage *pNext;              /* Next saved page in the same savepoint */
  int iSavepoint;                 /* Transaction number of savepoint */
272
273
274
275
276
277
278

279
280
281
282
283
284
285

    aNew = sqlite4_realloc(p->btl.pEnv, p->aSavepoint, nByte);
    if( aNew ){
      int i;
      for(i=p->nSavepoint; i<nReq; i++){
        aNew[i].pSavepage = 0;
        aNew[i].iLevel = i+3;

      }
      p->aSavepoint = aNew;
      p->nSavepoint = nReq;
    }else{
      rc = btErrorBkpt(SQLITE4_NOMEM);
    }
  }







>







273
274
275
276
277
278
279
280
281
282
283
284
285
286
287

    aNew = sqlite4_realloc(p->btl.pEnv, p->aSavepoint, nByte);
    if( aNew ){
      int i;
      for(i=p->nSavepoint; i<nReq; i++){
        aNew[i].pSavepage = 0;
        aNew[i].iLevel = i+3;
        memcpy(&aNew[i].hdr, p->pHdr, sizeof(BtDbHdr));
      }
      p->aSavepoint = aNew;
      p->nSavepoint = nReq;
    }else{
      rc = btErrorBkpt(SQLITE4_NOMEM);
    }
  }
370
371
372
373
374
375
376




377
378
379
380
381
382
383

  if( nReq<=p->nSavepoint ){
    int i;
    for(i=p->nSavepoint-1; i>=nReq; i--){
      BtSavepoint *pSavepoint = &p->aSavepoint[i];
      BtSavepage *pSavepg;
      BtSavepage *pNext;





      /* Loop through each of the BtSavepage objects associated with this
      ** savepoint. Detach them from the BtPage objects and free all
      ** allocated memory.  */
      for(pSavepg=pSavepoint->pSavepage; pSavepg; pSavepg=pNext){
        BtPage *pPg = pSavepg->pPg;
        pNext = pSavepg->pNext;







>
>
>
>







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389

  if( nReq<=p->nSavepoint ){
    int i;
    for(i=p->nSavepoint-1; i>=nReq; i--){
      BtSavepoint *pSavepoint = &p->aSavepoint[i];
      BtSavepage *pSavepg;
      BtSavepage *pNext;

      /* Restore the BtDbHdr object to the state it was in at the start of
      ** this savepoint.  */
      memcpy(p->pHdr, &pSavepoint->hdr, sizeof(BtDbHdr));

      /* Loop through each of the BtSavepage objects associated with this
      ** savepoint. Detach them from the BtPage objects and free all
      ** allocated memory.  */
      for(pSavepg=pSavepoint->pSavepage; pSavepg; pSavepg=pNext){
        BtPage *pPg = pSavepg->pPg;
        pNext = pSavepg->pNext;
647
648
649
650
651
652
653

654
655
656
657
658
659
660
      btHashRemove(p, pPg);
      btFreePage(p, pPg);
    }else if( rc==SQLITE4_OK && (pPg->pgno<=p->pHdr->nPg) ){
      rc = btLoadPageData(p, pPg);
    }
  }
  p->pDirty = 0;


  return rc;
}

/*
** Transactions. These methods are more or less the same as their 
** counterparts in bt.h.







>







653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
      btHashRemove(p, pPg);
      btFreePage(p, pPg);
    }else if( rc==SQLITE4_OK && (pPg->pgno<=p->pHdr->nPg) ){
      rc = btLoadPageData(p, pPg);
    }
  }
  p->pDirty = 0;
  sqlite4BtLogReloadDbHdr(p->pLog);

  return rc;
}

/*
** Transactions. These methods are more or less the same as their 
** counterparts in bt.h.