If the original author bothered to set TEMP_STORE to "always memory", I would 
take that as a strong indication that they are using TEMP tables for 
performance reasons.

Off the top of my head I would probably do:

CREATE TABLE log (id integer primary key, timestamp integer, data_item_1 float, 
...);
CREATE TEMP TABLE log_buffer (id integer primary key, timestamp integer, 
data_item_1 float, ...);

Insert 256 rows into log_buffer with id 0..255.

Keep track of the current id in software.

Logging executes the prepared statement: UPDATE log_buffer SET ... WHERE id = 
:CURR; and increments the rowid

If the current rowid hits 128 (or 256, where it wraps to 0 without extra action 
if you use an uint8_t):

BEGIN;
INSERT INTO log (SELECT * FROM log_buffer WHERE id < 128);
UPDATE log_buffer SET ... WHERE id <128);
COMMIT;

This would copy the buffered records to persistent storage while significantly 
reduding the IO load to flash. The copy over is fast and thus reduces the risk 
of corruption.  Any data in the TEMP table would be lost during a hard power 
fail. Too bad. A copy over interrupted by the hard power fail would be rolled 
back on recovery. Hard luck. But the database would be quite resistant to 
corruption

-----Ursprüngliche Nachricht-----
Von: sqlite-users [mailto:sqlite-users-boun...@mailinglists.sqlite.org] Im 
Auftrag von Ted Goldblatt
Gesendet: Dienstag, 12. März 2019 22:42
An: SQLite mailing list <sqlite-users@mailinglists.sqlite.org>
Betreff: [EXTERNAL] Re: [sqlite] Apparent power fail data loss in embedded use 
- SQLite newbie

On Tue, Mar 12, 2019 at 12:17 PM Simon Slavin <slav...@bigfraud.org> wrote:

> Other posters have taken care of very important aspects of your
> circumstances, but I wanted to mention one I didn't see anyone mention.
> Settings.
>
> If you compile SQLite without changing compilation settings, and use
> it without changing defaults, SQLite is extremely good at avoiding
> corruption, and at recovering after corruption.  This includes
> corruption due to power-loss at any stage while changes are being made to the 
> database.
>
> However, settings can be made which improve SQLite for some specific
> uses.  They make it faster.  Or use less memory.  Or use less
> filespace while working.  Unfortunately some of them all sacrifice
> harness against corruption.
>
> These settings can be made at three (or more ?  not sure) different places:
>
> 1) Compilation settings when the SQLite API is compiled
> 2) Extra parameters passed when the database is opened
> 3) PRAGMA settings made at any time while the database is open
>
> To assess how 'hard' your use of SQLite is against corruption, you
> would have to track down whether any of the above three have been done.
>
> 1) May or may not be easy.  Do you know how SQLite is included in your
> project ?  Is it part of a library downloaded from somewhere or did
> your programmer compile it themself ?  If the former, you can assume
> that whoever prepared the library didn't mess with default settings.
> If the latter, can you track down the compilation settings they used ?
>
SQLite is built from (the combined) source as part of the project build. I 
don't see signs in the project options that any special (SQLite) settings are 
used.  However, the interface is done through the CppSQLite3 interface layer.  
(There have been some local changes to CppSQLite3, but they appear to be 
limited to adding error logging.)  There is also a local header file (that is, 
one written as part of the project) with what appear to be SQLite compilation 
options (SQLITE_OMIT_xxx, SQLITE_DEFAULT_CACHE_SIZE, SQLITE_THREADSAFE, etc.  
One of these is SQLITE_TEMP_STORE, which is set to "Always use memory" which 
strikes me a suspicious relative to a power fail problem.  However, I cannot 
find anything that seems to reference most of these, and specifically not the 
TEMP_STORE define.  And this file is only included by a project specific DB 
interface file that invokes CppSQLite3 methods but not by sqlite3.c, so I'm not 
sure of the point.

>
> 2) Do you have the source code for your project ?  Can you find all
> places where a database is opened ?  If it uses the SQLite API
> directly you can just search for "sqlite3_open".  See whether you can
> spot whether anything except file name & path are passed.
>
I have full sources.   The DB opens are directly by CppSQLite3 (which uses
sqlite_open_v2()), and all of those calls have OPEN_READONLY or OPEN_READWRITE 
as the 3rd param and 0 as the 4th.  The CppSQLite3 methods themselves take only 
a filename.

3) Do you have the source code for your project ?  Can you do a global
> search for "PRAGMA" ?  Only a few of the PRAGMAs reduce integrity.
> Most of them are fine.  But you can look them up and see for yourself.
>
 It doesn't appear that any PRAGMAs appear outside the CppSQLite3_16.cpp and 
sqlite3.h files.

>
> The whole of the above is merely me being picky.  Millions of SQLite
> users just leave all settings at their defaults.  But it seems to be
> the sort of thing you're asking about.
>
It is.  I am guessing that the problem isn't in SQLite, per se, but in the 
local config or usage.  However, clues about where to look are always welcome...
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


___________________________________________
 Gunter Hick | Software Engineer | Scientific Games International GmbH | 
Klitschgasse 2-4, A-1130 Vienna | FN 157284 a, HG Wien, DVR: 0430013 | (O) +43 
1 80100 - 0

May be privileged. May be confidential. Please delete if not the addressee.
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to