Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Rollback the transaction if an SQLITE_FULL error is encountered. This is a preliminary fix for ticket #2686. More testing and analysis is needed before we close the ticket. (CVS 4458) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
0fb6d5a5773c282882e7283e6f8f8c00 |
User & Date: | drh 2007-10-03 15:30:52.000 |
Context
2007-10-03
| ||
18:45 | Simplify the vdbeHalt logic slightly. (CVS 4459) (check-in: b59f7bcbab user: drh tags: trunk) | |
15:30 | Rollback the transaction if an SQLITE_FULL error is encountered. This is a preliminary fix for ticket #2686. More testing and analysis is needed before we close the ticket. (CVS 4458) (check-in: 0fb6d5a577 user: drh tags: trunk) | |
15:22 | Fix a memory leak that could occur during error-state recovery. (CVS 4457) (check-in: 3d1d13d1eb user: danielk1977 tags: trunk) | |
Changes
Changes to src/vdbeaux.c.
︙ | ︙ | |||
1348 1349 1350 1351 1352 1353 1354 | int (*xFunc)(Btree *pBt) = 0; /* Function to call on each btree backend */ int isSpecialError; /* Set to true if SQLITE_NOMEM or IOERR */ /* This function contains the logic that determines if a statement or ** transaction will be committed or rolled back as a result of the ** execution of this virtual machine. ** | | | | | < | < | < < | < < | < < < < < < | | | | 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 | int (*xFunc)(Btree *pBt) = 0; /* Function to call on each btree backend */ int isSpecialError; /* Set to true if SQLITE_NOMEM or IOERR */ /* This function contains the logic that determines if a statement or ** transaction will be committed or rolled back as a result of the ** execution of this virtual machine. ** ** If any of the following errors occur: ** ** SQLITE_NOMEM ** SQLITE_IOERR ** SQLITE_FULL ** SQLITE_INTERRUPT ** ** Then the internal cache might have been left in an inconsistent ** state. We need to rollback the statement transaction, if there is ** one, or the complete transaction if there is no statement transaction. */ if( p->db->mallocFailed ){ p->rc = SQLITE_NOMEM; } closeAllCursorsExceptActiveVtabs(p); if( p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_OK; } checkActiveVdbeCnt(db); /* No commit or rollback needed if the program never started */ if( p->pc>=0 ){ int mrc; /* Primary error code from p->rc */ /* Lock all btrees used by the statement */ sqlite3BtreeMutexArrayEnter(&p->aMutex); /* Check for one of the special errors */ mrc = p->rc & 0xff; isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL ; if( isSpecialError ){ /* This loop does static analysis of the query to see which of the ** following three categories it falls into: ** ** Read-only ** Query with statement journal ** Query without statement journal |
︙ | ︙ | |||
1440 1441 1442 1443 1444 1445 1446 | /* If the query was read-only, we need do no rollback at all. Otherwise, ** proceed with the special handling. */ if( !isReadOnly ){ if( p->rc==SQLITE_IOERR_BLOCKED && isStatement ){ xFunc = sqlite3BtreeRollbackStmt; p->rc = SQLITE_BUSY; | | | 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 | /* If the query was read-only, we need do no rollback at all. Otherwise, ** proceed with the special handling. */ if( !isReadOnly ){ if( p->rc==SQLITE_IOERR_BLOCKED && isStatement ){ xFunc = sqlite3BtreeRollbackStmt; p->rc = SQLITE_BUSY; } else if( (p->rc==SQLITE_NOMEM || p->rc==SQLITE_FULL) && isStatement ){ xFunc = sqlite3BtreeRollbackStmt; }else{ /* We are forced to roll back the active transaction. Before doing ** so, abort any other statements this handle currently has active. */ invalidateCursorsOnModifiedBtrees(db); sqlite3RollbackAll(db); |
︙ | ︙ |
Added test/tkt2686.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | # 2007 Oct 3 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # This file is to test that ticket #2686 has been fixed. # # $Id: tkt2686.tcl,v 1.1 2007/10/03 15:30:52 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl db eval { PRAGMA page_size=1024; PRAGMA max_page_count=50; PRAGMA auto_vacuum=0; CREATE TABLE filler (fill); } for {set i 1} {$i<2000} {incr i} { do_test tkt2686-$i.1 { db eval BEGIN set rc [catch { while 1 { db eval {INSERT INTO filler (fill) VALUES (randstr(1000, 10000)) } } } msg] lappend rc $msg } {1 {database or disk is full}} do_test tkt2686-$i.2 { execsql { DELETE FROM filler WHERE rowid <= (SELECT MAX(rowid) FROM filler LIMIT 20) } } {} integrity_check tkt2686-$i.3 catch {db eval COMMIT} } finish_test |