mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Fix a database corruption problem that can occur in auto-vacuum mode when
a malloc() failure causes a statement rollback, additional statements are run in the same transaction, then the total transaction rolls back. (CVS 4079) FossilOrigin-Name: c9dcf2b926c99ff9cee68589f364461ab2a1d11f
This commit is contained in:
12
manifest
12
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Additional\sdebugging\sinstrumentation\sadded\sto\sthe\spager.\s(CVS\s4078)
|
C Fix\sa\sdatabase\scorruption\sproblem\sthat\scan\soccur\sin\sauto-vacuum\smode\swhen\na\smalloc()\sfailure\scauses\sa\sstatement\srollback,\sadditional\sstatements\nare\srun\sin\sthe\ssame\stransaction,\sthen\sthe\stotal\stransaction\srolls\sback.\s(CVS\s4079)
|
||||||
D 2007-06-16T03:06:28
|
D 2007-06-16T04:42:12
|
||||||
F Makefile.in b9971ab07868cf2b3209fe3bf8c52e7e25af4193
|
F Makefile.in b9971ab07868cf2b3209fe3bf8c52e7e25af4193
|
||||||
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
@@ -94,7 +94,7 @@ F src/os_unix.c f2ccf2e9a925fc679faf7a8fe85700e0f13cf0e1
|
|||||||
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
|
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
|
||||||
F src/os_win.c d868d5f9e95ec9c1b9e2a30c54c996053db6dddd
|
F src/os_win.c d868d5f9e95ec9c1b9e2a30c54c996053db6dddd
|
||||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||||
F src/pager.c a4a02246d23edcc8113f5957d7db4772d9cd71bc
|
F src/pager.c a8e5c2fd00737ddd7d8c8416d0fdbbf904d78b64
|
||||||
F src/pager.h 94110a5570dca30d54a883e880a3633b2e4c05ae
|
F src/pager.h 94110a5570dca30d54a883e880a3633b2e4c05ae
|
||||||
F src/parse.y 2ed1d91fdcb4ae7ae7d1f4674544297807c7cc26
|
F src/parse.y 2ed1d91fdcb4ae7ae7d1f4674544297807c7cc26
|
||||||
F src/pragma.c 0d25dad58bdfd6789943a10f1b9663c2eb85b96d
|
F src/pragma.c 0d25dad58bdfd6789943a10f1b9663c2eb85b96d
|
||||||
@@ -506,7 +506,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||||
P 7d3c1f08a34fcf2ca5c79d6e58f713ae6a4b34e8
|
P dcdb20f81ae923f6f56d75c7b8b89a0b3abff954
|
||||||
R 22dcb4d1b3c757bf921381ac2ad50631
|
R e52cc159103410bf628cb2caa9ba87b2
|
||||||
U drh
|
U drh
|
||||||
Z aa8c8e6b272cf52bad3cb3c217bce91b
|
Z 5e8ccb501c2183f5e479995480e6033d
|
||||||
|
@@ -1 +1 @@
|
|||||||
dcdb20f81ae923f6f56d75c7b8b89a0b3abff954
|
c9dcf2b926c99ff9cee68589f364461ab2a1d11f
|
51
src/pager.c
51
src/pager.c
@@ -18,7 +18,7 @@
|
|||||||
** file simultaneously, or one process from reading the database while
|
** file simultaneously, or one process from reading the database while
|
||||||
** another is writing.
|
** another is writing.
|
||||||
**
|
**
|
||||||
** @(#) $Id: pager.c,v 1.344 2007/06/16 03:06:28 drh Exp $
|
** @(#) $Id: pager.c,v 1.345 2007/06/16 04:42:12 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_DISKIO
|
#ifndef SQLITE_OMIT_DISKIO
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
@@ -1106,13 +1106,14 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
|
|||||||
** This occurs when a page is changed prior to the start of a statement
|
** This occurs when a page is changed prior to the start of a statement
|
||||||
** then changed again within the statement. When rolling back such a
|
** then changed again within the statement. When rolling back such a
|
||||||
** statement we must not write to the original database unless we know
|
** statement we must not write to the original database unless we know
|
||||||
** for certain that original page contents are in the main rollback
|
** for certain that original page contents are synced into the main rollback
|
||||||
** journal. Otherwise, if a full ROLLBACK occurs after the statement
|
** journal. Otherwise, a power loss might leave modified data in the
|
||||||
** rollback the full ROLLBACK will not restore the page to its original
|
** database file without an entry in the rollback journal that can
|
||||||
** content. Two conditions must be met before writing to the database
|
** restore the database to its original form. Two conditions must be
|
||||||
** files. (1) the database must be locked. (2) we know that the original
|
** met before writing to the database files. (1) the database must be
|
||||||
** page content is in the main journal either because the page is not in
|
** locked. (2) we know that the original page content is fully synced
|
||||||
** cache or else it is marked as needSync==0.
|
** in the main journal either because the page is not in cache or else
|
||||||
|
** the page is marked as needSync==0.
|
||||||
*/
|
*/
|
||||||
pPg = pager_lookup(pPager, pgno);
|
pPg = pager_lookup(pPager, pgno);
|
||||||
PAGERTRACE4("PLAYBACK %d page %d hash(%08x)\n",
|
PAGERTRACE4("PLAYBACK %d page %d hash(%08x)\n",
|
||||||
@@ -4243,15 +4244,15 @@ void sqlite3PagerSetCodec(
|
|||||||
|
|
||||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||||
/*
|
/*
|
||||||
** Move the page identified by pData to location pgno in the file.
|
** Move the page pPg to location pgno in the file.
|
||||||
**
|
**
|
||||||
** There must be no references to the current page pgno. If current page
|
** There must be no references to the page previously located at
|
||||||
** pgno is not already in the rollback journal, it is not written there by
|
** pgno (which we call pPgOld) though that page is allowed to be
|
||||||
** by this routine. The same applies to the page pData refers to on entry to
|
** in cache. If the page previous located at pgno is not already
|
||||||
** this routine.
|
** in the rollback journal, it is not put there by by this routine.
|
||||||
**
|
**
|
||||||
** References to the page refered to by pData remain valid. Updating any
|
** References to the page pPg remain valid. Updating any
|
||||||
** meta-data associated with page pData (i.e. data stored in the nExtra bytes
|
** meta-data associated with pPg (i.e. data stored in the nExtra bytes
|
||||||
** allocated along with the page) is the responsibility of the caller.
|
** allocated along with the page) is the responsibility of the caller.
|
||||||
**
|
**
|
||||||
** A transaction must be active when this routine is called. It used to be
|
** A transaction must be active when this routine is called. It used to be
|
||||||
@@ -4260,7 +4261,7 @@ void sqlite3PagerSetCodec(
|
|||||||
** transaction is active).
|
** transaction is active).
|
||||||
*/
|
*/
|
||||||
int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno){
|
int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno){
|
||||||
PgHdr *pPgOld;
|
PgHdr *pPgOld; /* The page being overwritten. */
|
||||||
int h;
|
int h;
|
||||||
Pgno needSyncPgno = 0;
|
Pgno needSyncPgno = 0;
|
||||||
|
|
||||||
@@ -4286,17 +4287,23 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno){
|
|||||||
** page pgno before the 'move' operation, it needs to be retained
|
** page pgno before the 'move' operation, it needs to be retained
|
||||||
** for the page moved there.
|
** for the page moved there.
|
||||||
*/
|
*/
|
||||||
|
pPg->needSync = 0;
|
||||||
pPgOld = pager_lookup(pPager, pgno);
|
pPgOld = pager_lookup(pPager, pgno);
|
||||||
if( pPgOld ){
|
if( pPgOld ){
|
||||||
assert( pPgOld->nRef==0 );
|
assert( pPgOld->nRef==0 );
|
||||||
unlinkHashChain(pPager, pPgOld);
|
unlinkHashChain(pPager, pPgOld);
|
||||||
makeClean(pPgOld);
|
makeClean(pPgOld);
|
||||||
if( pPgOld->needSync ){
|
pPg->needSync = pPgOld->needSync;
|
||||||
assert( pPgOld->inJournal );
|
}else{
|
||||||
pPg->inJournal = 1;
|
pPg->needSync = 0;
|
||||||
pPg->needSync = 1;
|
}
|
||||||
assert( pPager->needSync );
|
if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
|
||||||
}
|
pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;
|
||||||
|
}else if( (int)pgno>=pPager->origDbSize ){
|
||||||
|
pPg->inJournal = 1;
|
||||||
|
}else{
|
||||||
|
pPg->inJournal = 0;
|
||||||
|
assert( pPg->needSync==0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Change the page number for pPg and insert it into the new hash-chain. */
|
/* Change the page number for pPg and insert it into the new hash-chain. */
|
||||||
|
Reference in New Issue
Block a user