Add the "PRAGMA secure_delete=FAST" option, which overwrites most deleted

content without increasing the amount of I/O.  Deleted content might persist
on the free page list, however.  And extra CPU cycles are used for zeroing,
of course.

FossilOrigin-Name: 38978ce65b280bb7cba3fc08ba91485fb1b84cd9fbba2e950ecf41c021ff452a
This commit is contained in:
drh 2017-07-07 20:06:28 +00:00
commit 08f1efeb16
5 changed files with 51 additions and 27 deletions

View File

@ -1,5 +1,5 @@
C Change\sthe\serror\smessage\stext\sfor\sSQLITE_ERROR\sto\somit\sthe\spart\sabout\n"missing\sdatabase"\sas\sthat\smeaning\sis\snow\sobsolete\s(since\sapprox\sSQLite\s2.0).
D 2017-07-07T19:43:23.476
C Add\sthe\s"PRAGMA\ssecure_delete=FAST"\soption,\swhich\soverwrites\smost\sdeleted\ncontent\swithout\sincreasing\sthe\samount\sof\sI/O.\s\sDeleted\scontent\smight\spersist\non\sthe\sfree\spage\slist,\showever.\s\sAnd\sextra\sCPU\scycles\sare\sused\sfor\szeroing,\nof\scourse.
D 2017-07-07T20:06:28.516
F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba
@ -391,9 +391,9 @@ F src/auth.c 79f96c6f33bf0e5da8d1c282cee5ebb1852bb8a6ccca3e485d7c459b035d9c3c
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
F src/btree.c 00579ff9c2831d6f98cc993f8f2a34c0ff996e89b3cd2f27928f75796bc3a58a
F src/btree.c 79fb003347c47c74f8fda24f2fd332321da616771cd3d1b3258b739f569ec625
F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca
F src/btreeInt.h a392d353104b4add58b4a59cb185f5d5693dde832c565b77d8d4c343ed98f610
F src/btreeInt.h 97700795edf8a43245720414798b7b29d8e465aef46bf301ffacd431910c0da1
F src/build.c 74108007d286232fb4290464ee5452fa860c26215f8caa0e6c7cbf69a6fafe8f
F src/callback.c 8e14b60d1ed1c87c02cb5f121ecda99224f2aea6524a77ee6f72c9b5c7110f84
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
@ -441,7 +441,7 @@ F src/parse.y 71bf06b02f567232deabe258641b03e833e93c4dee61a120765ad74c13e7faec
F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870
F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11
F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc
F src/pragma.c 79ec7625d56130dbadf287a29b0ebf22167465049646366ad860a694f4547768
F src/pragma.c 54e64a9d65e2c3b6ef11d4ca732c6abc8b67f5e886f222ffe2cbf3506c4efbd2
F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324
F src/prepare.c 4b84ae7458febe1df3e04ae62ba56abc851f771340e460d14426e6802c5615f4
F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2
@ -1628,7 +1628,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 0961ec873b78ad2da0ea9cdf2934bc8f08276375a153fe5d9fa8d4280328deef
R 79fe59dfa4a836939eb45a203b110400
P 732f90d6327c5c6368fc8b4cc207bd644ef08e3ae6d2e7295258ab099deaba63 f1682f0faf1a93ded066464b1ddd5f987e21ee0f6bb5e828ed31c3ad903cf2c3
R 1f238fbce697fb2308131c37c5985e85
T +closed f1682f0faf1a93ded066464b1ddd5f987e21ee0f6bb5e828ed31c3ad903cf2c3
U drh
Z 8d02d118072fdff02038158664ac514a
Z c2c4f30ab3360a9e7249032b4e3580ff

View File

@ -1 +1 @@
732f90d6327c5c6368fc8b4cc207bd644ef08e3ae6d2e7295258ab099deaba63
38978ce65b280bb7cba3fc08ba91485fb1b84cd9fbba2e950ecf41c021ff452a

View File

@ -1640,7 +1640,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
/* Overwrite deleted information with zeros when the secure_delete
** option is enabled */
if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){
if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){
memset(&data[iStart], 0, iSize);
}
@ -1931,7 +1931,7 @@ static void zeroPage(MemPage *pPage, int flags){
assert( sqlite3PagerGetData(pPage->pDbPage) == data );
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
assert( sqlite3_mutex_held(pBt->mutex) );
if( pBt->btsFlags & BTS_SECURE_DELETE ){
if( pBt->btsFlags & BTS_FAST_SECURE ){
memset(&data[hdr], 0, pBt->usableSize - hdr);
}
data[hdr] = (char)flags;
@ -2354,8 +2354,10 @@ int sqlite3BtreeOpen(
pBt->pCursor = 0;
pBt->pPage1 = 0;
if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY;
#ifdef SQLITE_SECURE_DELETE
#if defined(SQLITE_SECURE_DELETE)
pBt->btsFlags |= BTS_SECURE_DELETE;
#elif defined(SQLITE_FAST_SECURE_DELETE)
pBt->btsFlags |= BTS_OVERWRITE;
#endif
/* EVIDENCE-OF: R-51873-39618 The page size for a database file is
** determined by the 2-byte integer located at an offset of 16 bytes from
@ -2803,19 +2805,34 @@ int sqlite3BtreeMaxPageCount(Btree *p, int mxPage){
}
/*
** Set the BTS_SECURE_DELETE flag if newFlag is 0 or 1. If newFlag is -1,
** then make no changes. Always return the value of the BTS_SECURE_DELETE
** setting after the change.
** Change the values for the BTS_SECURE_DELETE and BTS_OVERWRITE flags:
**
** newFlag==0 Both BTS_SECURE_DELETE and BTS_OVERWRITE are cleared
** newFlag==1 BTS_SECURE_DELETE set and BTS_OVERWRITE is cleared
** newFlag==2 BTS_SECURE_DELETE cleared and BTS_OVERWRITE is set
** newFlag==(-1) No changes
**
** This routine acts as a query if newFlag is less than zero
**
** With BTS_OVERWRITE set, deleted content is overwritten by zeros, but
** freelist leaf pages are not written back to the database. Thus in-page
** deleted content is cleared, but freelist deleted content is not.
**
** With BTS_SECURE_DELETE, operation is like BTS_OVERWRITE with the addition
** that freelist leaf pages are written back into the database, increasing
** the amount of disk I/O.
*/
int sqlite3BtreeSecureDelete(Btree *p, int newFlag){
int b;
if( p==0 ) return 0;
sqlite3BtreeEnter(p);
assert( BTS_OVERWRITE==BTS_SECURE_DELETE*2 );
assert( BTS_FAST_SECURE==(BTS_OVERWRITE|BTS_SECURE_DELETE) );
if( newFlag>=0 ){
p->pBt->btsFlags &= ~BTS_SECURE_DELETE;
if( newFlag ) p->pBt->btsFlags |= BTS_SECURE_DELETE;
}
b = (p->pBt->btsFlags & BTS_SECURE_DELETE)!=0;
p->pBt->btsFlags &= ~BTS_FAST_SECURE;
p->pBt->btsFlags |= BTS_SECURE_DELETE*newFlag;
}
b = (p->pBt->btsFlags & BTS_FAST_SECURE)/BTS_SECURE_DELETE;
sqlite3BtreeLeave(p);
return b;
}
@ -7210,7 +7227,7 @@ static int balance_nonroot(
** In this case, temporarily copy the cell into the aOvflSpace[]
** buffer. It will be copied out again as soon as the aSpace[] buffer
** is allocated. */
if( pBt->btsFlags & BTS_SECURE_DELETE ){
if( pBt->btsFlags & BTS_FAST_SECURE ){
int iOff;
iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData);

View File

@ -448,10 +448,12 @@ struct BtShared {
#define BTS_READ_ONLY 0x0001 /* Underlying file is readonly */
#define BTS_PAGESIZE_FIXED 0x0002 /* Page size can no longer be changed */
#define BTS_SECURE_DELETE 0x0004 /* PRAGMA secure_delete is enabled */
#define BTS_INITIALLY_EMPTY 0x0008 /* Database was empty at trans start */
#define BTS_NO_WAL 0x0010 /* Do not open write-ahead-log files */
#define BTS_EXCLUSIVE 0x0020 /* pWriter has an exclusive lock */
#define BTS_PENDING 0x0040 /* Waiting for read-locks to clear */
#define BTS_OVERWRITE 0x0008 /* Overwrite deleted content with zeros */
#define BTS_FAST_SECURE 0x000c /* Combination of the previous two */
#define BTS_INITIALLY_EMPTY 0x0010 /* Database was empty at trans start */
#define BTS_NO_WAL 0x0020 /* Do not open write-ahead-log files */
#define BTS_EXCLUSIVE 0x0040 /* pWriter has an exclusive lock */
#define BTS_PENDING 0x0080 /* Waiting for read-locks to clear */
/*
** An instance of the following structure is used to hold information

View File

@ -515,18 +515,22 @@ void sqlite3Pragma(
/*
** PRAGMA [schema.]secure_delete
** PRAGMA [schema.]secure_delete=ON/OFF
** PRAGMA [schema.]secure_delete=ON/OFF/FAST
**
** The first form reports the current setting for the
** secure_delete flag. The second form changes the secure_delete
** flag setting and reports thenew value.
** flag setting and reports the new value.
*/
case PragTyp_SECURE_DELETE: {
Btree *pBt = pDb->pBt;
int b = -1;
assert( pBt!=0 );
if( zRight ){
b = sqlite3GetBoolean(zRight, 0);
if( sqlite3_stricmp(zRight, "fast")==0 ){
b = 2;
}else{
b = sqlite3GetBoolean(zRight, 0);
}
}
if( pId2->n==0 && b>=0 ){
int ii;