[sqlite] SQLite with wall enabled what's wrong C demo

2016-03-24 Thread Olivier Mascia
> Le 24 mars 2016 ? 14:46, Domingo Alvarez Duarte  dev.dadbiz.es> a ?crit :
> 
> But in this example there is only one application accessing the database and
> only one table with one small record been updated all the time and no active
> readers, why it's writing to wal ?

Because it is engineered to do it that way, which is needed to achieve its 
goal(s).

https://sqlite.org/wal.html:

? WAL is significantly faster in most scenarios.
? WAL provides more concurrency as readers do not block writers and a writer 
does not block readers. Reading and writing can proceed concurrently.
? Disk I/O operations tends to be more sequential using WAL.
? WAL uses many fewer fsync() operations and is thus less vulnerable to 
problems on systems where the fsync() system call is broken.

> And why not update the same record instead of adding a new one in such
> situation ?  

I suppose you wanted to say: why add a new transaction slot to WAL, instead of 
directly updating the record within the main database file? If that is so, then 
the answer is: for the same reason as above.

One big WAL advantage is to allow you to have multiple readers, each of them 
having a stable view on the database content (NOT seeing committed 
transactions), for the duration of their (explicit) transaction, even though at 
the same time, any number of write transactions might occur (one writer at a 
time). 

By default, once the WAL file stores about 1000 pages (or more), a 
'checkpointing' operation will be attempted on each new commit, trying to merge 
as much transactions as possible from the WAL to the main database file. As 
there may be active readers still needing some of these transactions (to 
maintain their stability view on the data), not necessarily all transactions 
can be merged back to the db at once. So the wal file might not be reset 
completely at that time, and it will continue to grow above 1000 pages. But 
eventually they will, unless you have a read transaction active for ever. And 
once all and every connections to the database will be closed, the very last 
one to close will take care of finalizing the checkpointing (if needed). The 
WAL additional files will disappear.

Maybe WAL is not suited for your use-case as there are disadvantages too: 
https://sqlite.org/wal.html.

-- 
Meilleures salutations, Met vriendelijke groeten, Best Regards,
Olivier Mascia, integral.be/om





[sqlite] SQLite with wall enabled what's wrong C demo

2016-03-24 Thread Domingo Alvarez Duarte
Hello !  

I pulled the trigger too soon !  

The wall file stop growing at 4MB as advertised.  

But in this example there is only one application accessing the database and
only one table with one small record been updated all the time and no active
readers, why it's writing to wal ?  

And why not update the same record instead of adding a new one in such
situation ?  

I'll try with a bigger record to see what happens.  

Cheers !  

?  
>  Thu Mar 24 2016 11:55:11 AM CET from "Domingo Alvarez Duarte"
>  Subject: [sqlite] SQLite with wall enabled
>what's wrong C demo
>
>  Hello ! 
> 
> I'm sending here a C program that demonstrates the problem of sqlite3 in
>wall
> mode, 
> 
> in this simple example of a simulated session management for a web server
> when executing 
> 
> the wall log file will grow and grow till eat all our disk. 
> 
> ? 
> 
> There is something wrong with the program or with sqlite3 ? 
> 
> Cheers ! 
> 
> ? 
> 
> #include 
> #include 
> #include 
> #include 
> #include "sqlite3.h"
> 
> 
> static const char create_sql[] = "create table if not exists sessions(id
>text
> primary key, data text, ip_address, cdate datetime default
>CURRENT_TIMESTAMP,
> mdate datetime);";
> static const char insert_sql[] = "insert or ignore into sessions(id, data,
> ip_address, mdate) values(?,?,?, CURRENT_TIMESTAMP)";
> static const char update_sql[] = "update sessions set data=?,
> mdate=CURRENT_TIMESTAMP where id=?";
> static const char select_sql[] = "select data from sessions where id=? and
> ip_address=?";
> 
> static volatile int keepRunning = 1;
> 
> void intHandler(int dummy) {
> ??? keepRunning = 0;
> }
> 
> int main()
> {
> ??? signal(SIGINT, intHandler);
> 
> ??? printf("Starting our busy session management !\n");
> ??? sqlite3 *db;
> ??? int rc = sqlite3_open("sessions.db", &db);
> 
> ??? if(rc == SQLITE_OK)
> ??? {
> ??? sqlite3_stmt *stmt_insert, *stmt_update, *stmt_select;
> ??? //rc = sqlite3_exec(db, "PRAGMA synchronous = 0;", NULL,
>NULL,
> NULL);
> ??? rc = sqlite3_exec(db, "PRAGMA journal_mode = WAL;", NULL,
> NULL, NULL);
> 
> ??? //create sessions table
> ??? rc = sqlite3_exec(db, create_sql, NULL, NULL, NULL);
> 
> ??? //create prepared statements
> ??? rc = sqlite3_prepare_v2(db, insert_sql,
>sizeof(insert_sql)-1,
> &stmt_insert, NULL);
> ??? rc = sqlite3_prepare_v2(db, update_sql,
>sizeof(update_sql)-1,
> &stmt_update, NULL);
> ??? rc = sqlite3_prepare_v2(db, select_sql,
>sizeof(select_sql)-1,
> &stmt_select, NULL);
> 
> ??? const char session_id[] = "ABC123456789";
> ??? const char ip_address[] = "127.0.0.1";
> ??? const char data[] = "a kind of initial data";
> 
> ??? //insert initial data
> ??? rc = sqlite3_bind_text(stmt_insert, 1, session_id,
> sizeof(session_id)-1, NULL);
> ??? rc = sqlite3_bind_text(stmt_insert, 2, data, sizeof(data)-1,
> NULL);
> ??? rc = sqlite3_bind_text(stmt_insert, 3, ip_address,
> sizeof(ip_address)-1, NULL);
> ??? rc = sqlite3_step(stmt_insert);
> ??? rc = sqlite3_reset(stmt_insert);
> 
> ??? int count = 0;
> ??? //start our busy long work
> ??? while(keepRunning)
> ??? {
> ??? printf("Managing session %d\n", ++count);
> ??? sleep(1);
> ??? //one client arrived, let's get it's saved data
> ??? rc = sqlite3_bind_text(stmt_select, 1, session_id,
> sizeof(session_id)-1, NULL);
> ??? rc = sqlite3_bind_text(stmt_select, 2, ip_address,
> sizeof(ip_address)-1, NULL);
> ??? rc = sqlite3_step(stmt_select);
> ??? const unsigned char *saved_data =
> sqlite3_column_text(stmt_select, 0);
> ??? rc = sqlite3_reset(stmt_select);
> 
> ??? sleep(1);
> ??? //ok we served our client, let's save it's data
> ??? rc = sqlite3_bind_text(stmt_update, 1, saved_data ?
> "ok we have previous data" : data, -1, NULL);
> ??? rc = sqlite3_bind_text(stmt_update, 2, session_id,
> sizeof(session_id)-1, NULL);
> ??? rc = sqlite3_step(stmt_update);
> ??? rc = sqlite3_reset(stmt_update);
> ??? }
> 
> ??? sqlite3_finalize(stmt_insert);
> ??? sqlite3_finalize(stmt_update);
> ??? sqlite3_finalize(stmt_select);
> ??? sqlite3_close(db);
> ??? }
> 
> ??? return 0;
> }
> 
> 
> 
> ?
> 
> ___
> sqlite-users mailing list
> sqlite-users at mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
> 
>
>  



?



[sqlite] SQLite with wall enabled what's wrong C demo

2016-03-24 Thread Domingo Alvarez Duarte
Thanks for reply !  

The error check was left out intentionally to not pollute the code, I stepped
through all code with gdb to certify it's doing all correctly.  

Cheers !  
>  Thu Mar 24 2016 12:03:28 PM CET from "Stephan Beal"
>  Subject: Re: [sqlite] SQLite with wall enabled
>what's wrong C demo
>
>  On Thu, Mar 24, 2016 at 11:55 AM, Domingo Alvarez Duarte <
> sqlite-mail at dev.dadbiz.es> wrote:
> 
>  
>>There is something wrong with the program or with sqlite3 ?
>> 
>> 
>> 
>> 
>> rc = sqlite3_bind_text(stmt_insert, 1, session_id,
>> sizeof(session_id)-1, NULL);
>> rc = sqlite3_bind_text(stmt_insert, 2, data, sizeof(data)-1,
>> NULL);
>> rc = sqlite3_bind_text(stmt_insert, 3, ip_address,
>> sizeof(ip_address)-1, NULL);
>> rc = sqlite3_step(stmt_insert);
>> rc = sqlite3_reset(stmt_insert);
>> 
>> 

>  You have not checked a single error code there. If you'll check those
> codes, you may be able to find out immediately what the problem is.
> 
> A Golden Rule of C APIs is: if you ignore the result codes, the API may
> ignore you.
> 
> -- 
> - stephan beal
> http://wanderinghorse.net/home/stephan/
> http://gplus.to/sgbeal
> "Freedom is sloppy. But since tyranny's the only guaranteed byproduct of
> those who insist on a perfect world, freedom will have to do." -- Bigby
>Wolf
> ___
> sqlite-users mailing list
> sqlite-users at mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
> 
>
>  



?



[sqlite] SQLite with wall enabled what's wrong C demo

2016-03-24 Thread Stephan Beal
On Thu, Mar 24, 2016 at 11:55 AM, Domingo Alvarez Duarte <
sqlite-mail at dev.dadbiz.es> wrote:

> There is something wrong with the program or with sqlite3 ?
>
>


> rc = sqlite3_bind_text(stmt_insert, 1, session_id,
> sizeof(session_id)-1, NULL);
> rc = sqlite3_bind_text(stmt_insert, 2, data, sizeof(data)-1,
> NULL);
> rc = sqlite3_bind_text(stmt_insert, 3, ip_address,
> sizeof(ip_address)-1, NULL);
> rc = sqlite3_step(stmt_insert);
> rc = sqlite3_reset(stmt_insert);
>

You have not checked a single error code there. If you'll check those
codes, you may be able to find out immediately what the problem is.

A Golden Rule of C APIs is: if you ignore the result codes, the API may
ignore you.

-- 
- stephan beal
http://wanderinghorse.net/home/stephan/
http://gplus.to/sgbeal
"Freedom is sloppy. But since tyranny's the only guaranteed byproduct of
those who insist on a perfect world, freedom will have to do." -- Bigby Wolf


[sqlite] SQLite with wall enabled what's wrong C demo

2016-03-24 Thread Domingo Alvarez Duarte
Hello !  

I'm sending here a C program that demonstrates the problem of sqlite3 in wall
mode,  

in this simple example of a simulated session management for a web server
when executing  

the wall log file will grow and grow till eat all our disk.  

?  

There is something wrong with the program or with sqlite3 ?  

Cheers !  

?  

#include 
#include 
#include 
#include 
#include "sqlite3.h"


static const char create_sql[] = "create table if not exists sessions(id text
primary key, data text, ip_address, cdate datetime default CURRENT_TIMESTAMP,
mdate datetime);";
static const char insert_sql[] = "insert or ignore into sessions(id, data,
ip_address, mdate) values(?,?,?, CURRENT_TIMESTAMP)";
static const char update_sql[] = "update sessions set data=?,
mdate=CURRENT_TIMESTAMP where id=?";
static const char select_sql[] = "select data from sessions where id=? and
ip_address=?";

static volatile int keepRunning = 1;

void intHandler(int dummy) {
??? keepRunning = 0;
}

int main()
{
??? signal(SIGINT, intHandler);

??? printf("Starting our busy session management !\n");
??? sqlite3 *db;
??? int rc = sqlite3_open("sessions.db", &db);

??? if(rc == SQLITE_OK)
??? {
??? sqlite3_stmt *stmt_insert, *stmt_update, *stmt_select;
??? //rc = sqlite3_exec(db, "PRAGMA synchronous = 0;", NULL, NULL,
NULL);
??? rc = sqlite3_exec(db, "PRAGMA journal_mode = WAL;", NULL,
NULL, NULL);

??? //create sessions table
??? rc = sqlite3_exec(db, create_sql, NULL, NULL, NULL);

??? //create prepared statements
??? rc = sqlite3_prepare_v2(db, insert_sql, sizeof(insert_sql)-1,
&stmt_insert, NULL);
??? rc = sqlite3_prepare_v2(db, update_sql, sizeof(update_sql)-1,
&stmt_update, NULL);
??? rc = sqlite3_prepare_v2(db, select_sql, sizeof(select_sql)-1,
&stmt_select, NULL);

??? const char session_id[] = "ABC123456789";
??? const char ip_address[] = "127.0.0.1";
??? const char data[] = "a kind of initial data";

??? //insert initial data
??? rc = sqlite3_bind_text(stmt_insert, 1, session_id,
sizeof(session_id)-1, NULL);
??? rc = sqlite3_bind_text(stmt_insert, 2, data, sizeof(data)-1,
NULL);
??? rc = sqlite3_bind_text(stmt_insert, 3, ip_address,
sizeof(ip_address)-1, NULL);
??? rc = sqlite3_step(stmt_insert);
??? rc = sqlite3_reset(stmt_insert);

??? int count = 0;
??? //start our busy long work
??? while(keepRunning)
??? {
??? printf("Managing session %d\n", ++count);
??? sleep(1);
??? //one client arrived, let's get it's saved data
??? rc = sqlite3_bind_text(stmt_select, 1, session_id,
sizeof(session_id)-1, NULL);
??? rc = sqlite3_bind_text(stmt_select, 2, ip_address,
sizeof(ip_address)-1, NULL);
??? rc = sqlite3_step(stmt_select);
??? const unsigned char *saved_data =
sqlite3_column_text(stmt_select, 0);
??? rc = sqlite3_reset(stmt_select);

??? sleep(1);
??? //ok we served our client, let's save it's data
??? rc = sqlite3_bind_text(stmt_update, 1, saved_data ?
"ok we have previous data" : data, -1, NULL);
??? rc = sqlite3_bind_text(stmt_update, 2, session_id,
sizeof(session_id)-1, NULL);
??? rc = sqlite3_step(stmt_update);
??? rc = sqlite3_reset(stmt_update);
??? }

??? sqlite3_finalize(stmt_insert);
??? sqlite3_finalize(stmt_update);
??? sqlite3_finalize(stmt_select);
??? sqlite3_close(db);
??? }

??? return 0;
}



?