4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give.
11 *************************************************************************
18 ** Thread 1. CREATE and DROP a table.
20 static char *stress_thread_1(int iTid
, void *pArg
){
21 Error err
= {0}; /* Error code and message */
22 Sqlite db
= {0}; /* SQLite database connection */
24 opendb(&err
, &db
, "test.db", 0);
25 while( !timetostop(&err
) ){
26 sql_script(&err
, &db
, "CREATE TABLE IF NOT EXISTS t1(a PRIMARY KEY, b)");
27 clear_error(&err
, SQLITE_LOCKED
);
28 sql_script(&err
, &db
, "DROP TABLE IF EXISTS t1");
29 clear_error(&err
, SQLITE_LOCKED
);
32 print_and_free_err(&err
);
33 return sqlite3_mprintf("ok");
37 ** Thread 2. Open and close database connections.
39 static char *stress_thread_2(int iTid
, void *pArg
){
40 Error err
= {0}; /* Error code and message */
41 Sqlite db
= {0}; /* SQLite database connection */
42 while( !timetostop(&err
) ){
43 opendb(&err
, &db
, "test.db", 0);
44 sql_script(&err
, &db
, "SELECT * FROM sqlite_schema;");
45 clear_error(&err
, SQLITE_LOCKED
);
48 print_and_free_err(&err
);
49 return sqlite3_mprintf("ok");
53 ** Thread 3. Attempt many small SELECT statements.
55 static char *stress_thread_3(int iTid
, void *pArg
){
56 Error err
= {0}; /* Error code and message */
57 Sqlite db
= {0}; /* SQLite database connection */
62 opendb(&err
, &db
, "test.db", 0);
63 while( !timetostop(&err
) ){
64 sql_script(&err
, &db
, "SELECT * FROM t1 ORDER BY a;");
67 clear_error(&err
, SQLITE_LOCKED
);
68 clear_error(&err
, SQLITE_ERROR
);
71 print_and_free_err(&err
);
72 return sqlite3_mprintf("read t1 %d/%d attempts", i2
, i1
);
76 ** Thread 5. Attempt INSERT statements.
78 static char *stress_thread_4(int iTid
, void *pArg
){
79 Error err
= {0}; /* Error code and message */
80 Sqlite db
= {0}; /* SQLite database connection */
83 int iArg
= PTR2INT(pArg
);
85 opendb(&err
, &db
, "test.db", 0);
86 while( !timetostop(&err
) ){
89 opendb(&err
, &db
, "test.db", 0);
92 "WITH loop(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM loop LIMIT 200) "
93 "INSERT INTO t1 VALUES(randomblob(60), randomblob(60));"
97 clear_error(&err
, SQLITE_LOCKED
);
98 clear_error(&err
, SQLITE_ERROR
);
101 print_and_free_err(&err
);
102 return sqlite3_mprintf("wrote t1 %d/%d attempts", i2
, i1
);
106 ** Thread 6. Attempt DELETE operations.
108 static char *stress_thread_5(int iTid
, void *pArg
){
109 Error err
= {0}; /* Error code and message */
110 Sqlite db
= {0}; /* SQLite database connection */
111 int iArg
= PTR2INT(pArg
);
116 opendb(&err
, &db
, "test.db", 0);
117 while( !timetostop(&err
) ){
121 opendb(&err
, &db
, "test.db", 0);
123 execsql(&err
, &db
, "DELETE FROM t1 WHERE (rowid % 4)==:i", &i
);
126 clear_error(&err
, SQLITE_LOCKED
);
129 print_and_free_err(&err
);
130 return sqlite3_mprintf("deleted from t1 %d/%d attempts", i2
, i1
);
134 static void stress1(int nMs
){
136 Threadset threads
= {0};
138 setstoptime(&err
, nMs
);
139 sqlite3_enable_shared_cache(1);
141 launch_thread(&err
, &threads
, stress_thread_1
, 0);
142 launch_thread(&err
, &threads
, stress_thread_1
, 0);
144 launch_thread(&err
, &threads
, stress_thread_2
, 0);
145 launch_thread(&err
, &threads
, stress_thread_2
, 0);
147 launch_thread(&err
, &threads
, stress_thread_3
, 0);
148 launch_thread(&err
, &threads
, stress_thread_3
, 0);
150 launch_thread(&err
, &threads
, stress_thread_4
, 0);
151 launch_thread(&err
, &threads
, stress_thread_4
, 0);
153 launch_thread(&err
, &threads
, stress_thread_5
, 0);
154 launch_thread(&err
, &threads
, stress_thread_5
, (void*)1);
156 join_all_threads(&err
, &threads
);
157 sqlite3_enable_shared_cache(0);
159 print_and_free_err(&err
);
162 /**************************************************************************
163 ***************************************************************************
164 ** Start of test case "stress2"
170 ** 1. CREATE TABLE statements.
171 ** 2. DROP TABLE statements.
172 ** 3. Small SELECT statements.
173 ** 4. Big SELECT statements.
174 ** 5. Small INSERT statements.
175 ** 6. Big INSERT statements.
176 ** 7. Small UPDATE statements.
177 ** 8. Big UPDATE statements.
178 ** 9. Small DELETE statements.
179 ** 10. Big DELETE statements.
181 ** 14. Integrity-check.
182 ** 17. Switch the journal mode from delete to wal and back again.
183 ** 19. Open and close database connections rapidly.
186 #define STRESS2_TABCNT 5 /* count1 in SDS test */
188 #define STRESS2_COUNT2 200 /* count2 in SDS test */
189 #define STRESS2_COUNT3 57 /* count2 in SDS test */
191 static void stress2_workload1(Error
*pErr
, Sqlite
*pDb
, int i
){
192 int iTab
= (i
% (STRESS2_TABCNT
-1)) + 1;
193 sql_script_printf(pErr
, pDb
,
194 "CREATE TABLE IF NOT EXISTS t%d(x PRIMARY KEY, y, z);", iTab
198 static void stress2_workload2(Error
*pErr
, Sqlite
*pDb
, int i
){
199 int iTab
= (i
% (STRESS2_TABCNT
-1)) + 1;
200 sql_script_printf(pErr
, pDb
, "DROP TABLE IF EXISTS t%d;", iTab
);
203 static void stress2_workload3(Error
*pErr
, Sqlite
*pDb
, int i
){
204 sql_script(pErr
, pDb
, "SELECT * FROM t0 WHERE z = 'small'");
207 static void stress2_workload4(Error
*pErr
, Sqlite
*pDb
, int i
){
208 sql_script(pErr
, pDb
, "SELECT * FROM t0 WHERE z = 'big'");
211 static void stress2_workload5(Error
*pErr
, Sqlite
*pDb
, int i
){
212 sql_script(pErr
, pDb
,
213 "INSERT INTO t0 VALUES(hex(random()), hex(randomblob(200)), 'small');"
217 static void stress2_workload6(Error
*pErr
, Sqlite
*pDb
, int i
){
218 sql_script(pErr
, pDb
,
219 "INSERT INTO t0 VALUES(hex(random()), hex(randomblob(57)), 'big');"
223 static void stress2_workload7(Error
*pErr
, Sqlite
*pDb
, int i
){
224 sql_script_printf(pErr
, pDb
,
225 "UPDATE t0 SET y = hex(randomblob(200)) "
226 "WHERE x LIKE hex((%d %% 5)) AND z='small';"
230 static void stress2_workload8(Error
*pErr
, Sqlite
*pDb
, int i
){
231 sql_script_printf(pErr
, pDb
,
232 "UPDATE t0 SET y = hex(randomblob(57)) "
233 "WHERE x LIKE hex(%d %% 5) AND z='big';"
238 static void stress2_workload9(Error
*pErr
, Sqlite
*pDb
, int i
){
239 sql_script_printf(pErr
, pDb
,
240 "DELETE FROM t0 WHERE x LIKE hex(%d %% 5) AND z='small';", i
243 static void stress2_workload10(Error
*pErr
, Sqlite
*pDb
, int i
){
244 sql_script_printf(pErr
, pDb
,
245 "DELETE FROM t0 WHERE x LIKE hex(%d %% 5) AND z='big';", i
249 static void stress2_workload11(Error
*pErr
, Sqlite
*pDb
, int i
){
250 sql_script(pErr
, pDb
, "VACUUM");
253 static void stress2_workload14(Error
*pErr
, Sqlite
*pDb
, int i
){
254 sql_script(pErr
, pDb
, "PRAGMA integrity_check");
257 static void stress2_workload17(Error
*pErr
, Sqlite
*pDb
, int i
){
258 sql_script_printf(pErr
, pDb
,
259 "PRAGMA journal_mode = %q", (i
%2) ? "delete" : "wal"
263 static char *stress2_workload19(int iTid
, void *pArg
){
264 Error err
= {0}; /* Error code and message */
265 Sqlite db
= {0}; /* SQLite database connection */
266 const char *zDb
= (const char*)pArg
;
267 while( !timetostop(&err
) ){
268 opendb(&err
, &db
, zDb
, 0);
269 sql_script(&err
, &db
, "SELECT * FROM sqlite_schema;");
270 clear_error(&err
, SQLITE_LOCKED
);
273 print_and_free_err(&err
);
274 return sqlite3_mprintf("ok");
278 typedef struct Stress2Ctx Stress2Ctx
;
281 void (*xProc
)(Error
*, Sqlite
*, int);
284 static char *stress2_thread_wrapper(int iTid
, void *pArg
){
285 Stress2Ctx
*pCtx
= (Stress2Ctx
*)pArg
;
286 Error err
= {0}; /* Error code and message */
287 Sqlite db
= {0}; /* SQLite database connection */
291 while( !timetostop(&err
) ){
293 opendb(&err
, &db
, pCtx
->zDb
, 0);
294 for(cnt
=0; err
.rc
==SQLITE_OK
&& cnt
<STRESS2_TABCNT
; cnt
++){
295 pCtx
->xProc(&err
, &db
, i1
);
296 i2
+= (err
.rc
==SQLITE_OK
);
297 clear_error(&err
, SQLITE_LOCKED
);
303 print_and_free_err(&err
);
304 return sqlite3_mprintf("ok %d/%d", i2
, i1
);
307 static void stress2_launch_thread_loop(
308 Error
*pErr
, /* IN/OUT: Error code */
309 Threadset
*pThreads
, /* Thread set */
310 const char *zDb
, /* Database name */
311 void (*x
)(Error
*,Sqlite
*,int) /* Run this until error or timeout */
313 Stress2Ctx
*pCtx
= sqlite3_malloc(sizeof(Stress2Ctx
));
316 launch_thread(pErr
, pThreads
, stress2_thread_wrapper
, (void*)pCtx
);
319 static void stress2(int nMs
){
321 void (*x
)(Error
*,Sqlite
*,int);
323 { stress2_workload1
},
324 { stress2_workload2
},
325 { stress2_workload3
},
326 { stress2_workload4
},
327 { stress2_workload5
},
328 { stress2_workload6
},
329 { stress2_workload7
},
330 { stress2_workload8
},
331 { stress2_workload9
},
332 { stress2_workload10
},
333 { stress2_workload11
},
334 { stress2_workload14
},
335 { stress2_workload17
},
337 const char *zDb
= "test.db";
342 Threadset threads
= {0};
344 /* To make sure the db file is empty before commencing */
345 opendb(&err
, &db
, zDb
, 1);
346 sql_script(&err
, &db
,
347 "CREATE TABLE IF NOT EXISTS t0(x PRIMARY KEY, y, z);"
348 "CREATE INDEX IF NOT EXISTS i0 ON t0(y);"
352 setstoptime(&err
, nMs
);
353 sqlite3_enable_shared_cache(1);
355 for(i
=0; i
<sizeof(aTask
)/sizeof(aTask
[0]); i
++){
356 stress2_launch_thread_loop(&err
, &threads
, zDb
, aTask
[i
].x
);
358 launch_thread(&err
, &threads
, stress2_workload19
, (void*)zDb
);
359 launch_thread(&err
, &threads
, stress2_workload19
, (void*)zDb
);
361 join_all_threads(&err
, &threads
);
362 sqlite3_enable_shared_cache(0);
363 print_and_free_err(&err
);