2014-12-12 16:39:38 +00:00
/*
* * 2014 December 9
* *
* * 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 .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* *
*/
/*
* * Thread 1. CREATE and DROP a table .
*/
2014-12-13 17:41:48 +00:00
static char * stress_thread_1 ( int iTid , void * pArg ) {
2014-12-12 16:39:38 +00:00
Error err = { 0 } ; /* Error code and message */
Sqlite db = { 0 } ; /* SQLite database connection */
opendb ( & err , & db , " test.db " , 0 ) ;
while ( ! timetostop ( & err ) ) {
sql_script ( & err , & db , " CREATE TABLE IF NOT EXISTS t1(a PRIMARY KEY, b) " ) ;
clear_error ( & err , SQLITE_LOCKED ) ;
sql_script ( & err , & db , " DROP TABLE IF EXISTS t1 " ) ;
clear_error ( & err , SQLITE_LOCKED ) ;
}
closedb ( & err , & db ) ;
print_and_free_err ( & err ) ;
return sqlite3_mprintf ( " ok " ) ;
}
/*
* * Thread 2. Open and close database connections .
*/
2014-12-13 17:41:48 +00:00
static char * stress_thread_2 ( int iTid , void * pArg ) {
2014-12-12 16:39:38 +00:00
Error err = { 0 } ; /* Error code and message */
Sqlite db = { 0 } ; /* SQLite database connection */
while ( ! timetostop ( & err ) ) {
opendb ( & err , & db , " test.db " , 0 ) ;
2020-06-19 15:24:12 +00:00
sql_script ( & err , & db , " SELECT * FROM sqlite_schema; " ) ;
2014-12-12 16:39:38 +00:00
clear_error ( & err , SQLITE_LOCKED ) ;
closedb ( & err , & db ) ;
}
print_and_free_err ( & err ) ;
return sqlite3_mprintf ( " ok " ) ;
}
/*
* * Thread 3. Attempt many small SELECT statements .
*/
2014-12-13 17:41:48 +00:00
static char * stress_thread_3 ( int iTid , void * pArg ) {
2014-12-12 16:39:38 +00:00
Error err = { 0 } ; /* Error code and message */
Sqlite db = { 0 } ; /* SQLite database connection */
int i1 = 0 ;
int i2 = 0 ;
opendb ( & err , & db , " test.db " , 0 ) ;
while ( ! timetostop ( & err ) ) {
sql_script ( & err , & db , " SELECT * FROM t1 ORDER BY a; " ) ;
i1 + + ;
if ( err . rc ) i2 + + ;
clear_error ( & err , SQLITE_LOCKED ) ;
clear_error ( & err , SQLITE_ERROR ) ;
}
closedb ( & err , & db ) ;
print_and_free_err ( & err ) ;
return sqlite3_mprintf ( " read t1 %d/%d attempts " , i2 , i1 ) ;
}
/*
* * Thread 5. Attempt INSERT statements .
*/
2014-12-13 17:41:48 +00:00
static char * stress_thread_4 ( int iTid , void * pArg ) {
2014-12-12 16:39:38 +00:00
Error err = { 0 } ; /* Error code and message */
Sqlite db = { 0 } ; /* SQLite database connection */
int i1 = 0 ;
int i2 = 0 ;
2014-12-13 17:41:48 +00:00
int iArg = PTR2INT ( pArg ) ;
2014-12-12 16:39:38 +00:00
opendb ( & err , & db , " test.db " , 0 ) ;
while ( ! timetostop ( & err ) ) {
if ( iArg ) {
closedb ( & err , & db ) ;
opendb ( & err , & db , " test.db " , 0 ) ;
}
sql_script ( & err , & db ,
" WITH loop(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM loop LIMIT 200) "
" INSERT INTO t1 VALUES(randomblob(60), randomblob(60)); "
) ;
i1 + + ;
if ( err . rc ) i2 + + ;
clear_error ( & err , SQLITE_LOCKED ) ;
clear_error ( & err , SQLITE_ERROR ) ;
}
closedb ( & err , & db ) ;
print_and_free_err ( & err ) ;
return sqlite3_mprintf ( " wrote t1 %d/%d attempts " , i2 , i1 ) ;
}
/*
* * Thread 6. Attempt DELETE operations .
*/
2014-12-13 17:41:48 +00:00
static char * stress_thread_5 ( int iTid , void * pArg ) {
2014-12-12 16:39:38 +00:00
Error err = { 0 } ; /* Error code and message */
Sqlite db = { 0 } ; /* SQLite database connection */
2014-12-13 17:41:48 +00:00
int iArg = PTR2INT ( pArg ) ;
2014-12-12 16:39:38 +00:00
int i1 = 0 ;
int i2 = 0 ;
opendb ( & err , & db , " test.db " , 0 ) ;
while ( ! timetostop ( & err ) ) {
i64 i = ( i1 % 4 ) ;
if ( iArg ) {
closedb ( & err , & db ) ;
opendb ( & err , & db , " test.db " , 0 ) ;
}
execsql ( & err , & db , " DELETE FROM t1 WHERE (rowid % 4)==:i " , & i ) ;
i1 + + ;
if ( err . rc ) i2 + + ;
clear_error ( & err , SQLITE_LOCKED ) ;
}
closedb ( & err , & db ) ;
print_and_free_err ( & err ) ;
return sqlite3_mprintf ( " deleted from t1 %d/%d attempts " , i2 , i1 ) ;
}
static void stress1 ( int nMs ) {
Error err = { 0 } ;
Threadset threads = { 0 } ;
setstoptime ( & err , nMs ) ;
sqlite3_enable_shared_cache ( 1 ) ;
launch_thread ( & err , & threads , stress_thread_1 , 0 ) ;
launch_thread ( & err , & threads , stress_thread_1 , 0 ) ;
launch_thread ( & err , & threads , stress_thread_2 , 0 ) ;
launch_thread ( & err , & threads , stress_thread_2 , 0 ) ;
launch_thread ( & err , & threads , stress_thread_3 , 0 ) ;
launch_thread ( & err , & threads , stress_thread_3 , 0 ) ;
launch_thread ( & err , & threads , stress_thread_4 , 0 ) ;
launch_thread ( & err , & threads , stress_thread_4 , 0 ) ;
launch_thread ( & err , & threads , stress_thread_5 , 0 ) ;
2014-12-13 17:41:48 +00:00
launch_thread ( & err , & threads , stress_thread_5 , ( void * ) 1 ) ;
2014-12-12 16:39:38 +00:00
join_all_threads ( & err , & threads ) ;
sqlite3_enable_shared_cache ( 0 ) ;
print_and_free_err ( & err ) ;
}
2014-12-13 17:41:48 +00:00
/**************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * Start of test case " stress2 "
*/
/*
* * 1. CREATE TABLE statements .
* * 2. DROP TABLE statements .
* * 3. Small SELECT statements .
* * 4. Big SELECT statements .
* * 5. Small INSERT statements .
* * 6. Big INSERT statements .
* * 7. Small UPDATE statements .
* * 8. Big UPDATE statements .
* * 9. Small DELETE statements .
* * 10. Big DELETE statements .
* * 11. VACUUM .
* * 14. Integrity - check .
* * 17. Switch the journal mode from delete to wal and back again .
* * 19. Open and close database connections rapidly .
*/
2014-12-15 20:49:26 +00:00
# define STRESS2_TABCNT 5 /* count1 in SDS test */
# define STRESS2_COUNT2 200 /* count2 in SDS test */
# define STRESS2_COUNT3 57 /* count2 in SDS test */
2014-12-13 17:41:48 +00:00
static void stress2_workload1 ( Error * pErr , Sqlite * pDb , int i ) {
2014-12-15 20:49:26 +00:00
int iTab = ( i % ( STRESS2_TABCNT - 1 ) ) + 1 ;
2014-12-13 17:41:48 +00:00
sql_script_printf ( pErr , pDb ,
" CREATE TABLE IF NOT EXISTS t%d(x PRIMARY KEY, y, z); " , iTab
) ;
}
static void stress2_workload2 ( Error * pErr , Sqlite * pDb , int i ) {
2014-12-15 20:49:26 +00:00
int iTab = ( i % ( STRESS2_TABCNT - 1 ) ) + 1 ;
2014-12-13 17:41:48 +00:00
sql_script_printf ( pErr , pDb , " DROP TABLE IF EXISTS t%d; " , iTab ) ;
}
static void stress2_workload3 ( Error * pErr , Sqlite * pDb , int i ) {
2014-12-15 20:49:26 +00:00
sql_script ( pErr , pDb , " SELECT * FROM t0 WHERE z = 'small' " ) ;
2014-12-13 17:41:48 +00:00
}
static void stress2_workload4 ( Error * pErr , Sqlite * pDb , int i ) {
2014-12-15 20:49:26 +00:00
sql_script ( pErr , pDb , " SELECT * FROM t0 WHERE z = 'big' " ) ;
2014-12-13 17:41:48 +00:00
}
static void stress2_workload5 ( Error * pErr , Sqlite * pDb , int i ) {
2014-12-15 20:49:26 +00:00
sql_script ( pErr , pDb ,
" INSERT INTO t0 VALUES(hex(random()), hex(randomblob(200)), 'small'); "
2014-12-13 17:41:48 +00:00
) ;
}
static void stress2_workload6 ( Error * pErr , Sqlite * pDb , int i ) {
2014-12-15 20:49:26 +00:00
sql_script ( pErr , pDb ,
" INSERT INTO t0 VALUES(hex(random()), hex(randomblob(57)), 'big'); "
2014-12-13 17:41:48 +00:00
) ;
}
static void stress2_workload7 ( Error * pErr , Sqlite * pDb , int i ) {
sql_script_printf ( pErr , pDb ,
2014-12-15 20:49:26 +00:00
" UPDATE t0 SET y = hex(randomblob(200)) "
" WHERE x LIKE hex((%d %% 5)) AND z='small'; "
, i
2014-12-13 17:41:48 +00:00
) ;
}
static void stress2_workload8 ( Error * pErr , Sqlite * pDb , int i ) {
sql_script_printf ( pErr , pDb ,
2014-12-15 20:49:26 +00:00
" UPDATE t0 SET y = hex(randomblob(57)) "
" WHERE x LIKE hex(%d %% 5) AND z='big'; "
, i
2014-12-13 17:41:48 +00:00
) ;
}
static void stress2_workload9 ( Error * pErr , Sqlite * pDb , int i ) {
sql_script_printf ( pErr , pDb ,
2014-12-15 20:49:26 +00:00
" DELETE FROM t0 WHERE x LIKE hex(%d %% 5) AND z='small'; " , i
2014-12-13 17:41:48 +00:00
) ;
}
static void stress2_workload10 ( Error * pErr , Sqlite * pDb , int i ) {
sql_script_printf ( pErr , pDb ,
2014-12-15 20:49:26 +00:00
" DELETE FROM t0 WHERE x LIKE hex(%d %% 5) AND z='big'; " , i
2014-12-13 17:41:48 +00:00
) ;
}
static void stress2_workload11 ( Error * pErr , Sqlite * pDb , int i ) {
sql_script ( pErr , pDb , " VACUUM " ) ;
}
static void stress2_workload14 ( Error * pErr , Sqlite * pDb , int i ) {
sql_script ( pErr , pDb , " PRAGMA integrity_check " ) ;
}
static void stress2_workload17 ( Error * pErr , Sqlite * pDb , int i ) {
sql_script_printf ( pErr , pDb ,
" PRAGMA journal_mode = %q " , ( i % 2 ) ? " delete " : " wal "
) ;
}
static char * stress2_workload19 ( int iTid , void * pArg ) {
Error err = { 0 } ; /* Error code and message */
Sqlite db = { 0 } ; /* SQLite database connection */
const char * zDb = ( const char * ) pArg ;
while ( ! timetostop ( & err ) ) {
opendb ( & err , & db , zDb , 0 ) ;
2020-06-19 15:24:12 +00:00
sql_script ( & err , & db , " SELECT * FROM sqlite_schema; " ) ;
2014-12-13 17:41:48 +00:00
clear_error ( & err , SQLITE_LOCKED ) ;
closedb ( & err , & db ) ;
}
print_and_free_err ( & err ) ;
return sqlite3_mprintf ( " ok " ) ;
}
typedef struct Stress2Ctx Stress2Ctx ;
struct Stress2Ctx {
const char * zDb ;
void ( * xProc ) ( Error * , Sqlite * , int ) ;
} ;
static char * stress2_thread_wrapper ( int iTid , void * pArg ) {
Stress2Ctx * pCtx = ( Stress2Ctx * ) pArg ;
Error err = { 0 } ; /* Error code and message */
Sqlite db = { 0 } ; /* SQLite database connection */
int i1 = 0 ;
int i2 = 0 ;
while ( ! timetostop ( & err ) ) {
2014-12-15 20:49:26 +00:00
int cnt ;
opendb ( & err , & db , pCtx - > zDb , 0 ) ;
for ( cnt = 0 ; err . rc = = SQLITE_OK & & cnt < STRESS2_TABCNT ; cnt + + ) {
pCtx - > xProc ( & err , & db , i1 ) ;
i2 + = ( err . rc = = SQLITE_OK ) ;
clear_error ( & err , SQLITE_LOCKED ) ;
i1 + + ;
}
closedb ( & err , & db ) ;
2014-12-13 17:41:48 +00:00
}
print_and_free_err ( & err ) ;
return sqlite3_mprintf ( " ok %d/%d " , i2 , i1 ) ;
}
static void stress2_launch_thread_loop (
Error * pErr , /* IN/OUT: Error code */
Threadset * pThreads , /* Thread set */
const char * zDb , /* Database name */
void ( * x ) ( Error * , Sqlite * , int ) /* Run this until error or timeout */
) {
Stress2Ctx * pCtx = sqlite3_malloc ( sizeof ( Stress2Ctx ) ) ;
pCtx - > zDb = zDb ;
pCtx - > xProc = x ;
launch_thread ( pErr , pThreads , stress2_thread_wrapper , ( void * ) pCtx ) ;
}
static void stress2 ( int nMs ) {
struct Stress2Task {
void ( * x ) ( Error * , Sqlite * , int ) ;
} aTask [ ] = {
{ stress2_workload1 } ,
{ stress2_workload2 } ,
{ stress2_workload3 } ,
{ stress2_workload4 } ,
{ stress2_workload5 } ,
{ stress2_workload6 } ,
{ stress2_workload7 } ,
{ stress2_workload8 } ,
{ stress2_workload9 } ,
{ stress2_workload10 } ,
{ stress2_workload11 } ,
{ stress2_workload14 } ,
{ stress2_workload17 } ,
} ;
2014-12-15 20:49:26 +00:00
const char * zDb = " test.db " ;
2014-12-13 17:41:48 +00:00
2014-12-15 20:49:26 +00:00
int i ;
Error err = { 0 } ;
Sqlite db = { 0 } ;
Threadset threads = { 0 } ;
2014-12-13 17:41:48 +00:00
2014-12-15 20:49:26 +00:00
/* To make sure the db file is empty before commencing */
opendb ( & err , & db , zDb , 1 ) ;
sql_script ( & err , & db ,
" CREATE TABLE IF NOT EXISTS t0(x PRIMARY KEY, y, z); "
" CREATE INDEX IF NOT EXISTS i0 ON t0(y); "
) ;
closedb ( & err , & db ) ;
2014-12-13 17:41:48 +00:00
2014-12-15 20:49:26 +00:00
setstoptime ( & err , nMs ) ;
sqlite3_enable_shared_cache ( 1 ) ;
2014-12-13 17:41:48 +00:00
2014-12-15 20:49:26 +00:00
for ( i = 0 ; i < sizeof ( aTask ) / sizeof ( aTask [ 0 ] ) ; i + + ) {
stress2_launch_thread_loop ( & err , & threads , zDb , aTask [ i ] . x ) ;
2014-12-13 17:41:48 +00:00
}
2014-12-15 20:49:26 +00:00
launch_thread ( & err , & threads , stress2_workload19 , ( void * ) zDb ) ;
launch_thread ( & err , & threads , stress2_workload19 , ( void * ) zDb ) ;
join_all_threads ( & err , & threads ) ;
sqlite3_enable_shared_cache ( 0 ) ;
print_and_free_err ( & err ) ;
2014-12-13 17:41:48 +00:00
}