downgrade memory unlock failures to info level and fix function name in log output
[sqlcipher.git] / test / startup.c
blob7262189229606afa3818bf72714102d5bd50aff5
1 /*
2 ** 2021-01-01
3 **
4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
6 **
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 *************************************************************************
12 **
13 ** This file implements a program used to measure the start-up performance
14 ** of SQLite.
16 ** To use:
18 ** ./startup init
19 ** valgrind --tool=cachegrind ./startup run
22 ** The "./startup init" command creates the test database file named
23 ** "startup.db". The performance test is run by the "./startup run"
24 ** command. That command does nothing but open the database file and
25 ** parse the entire schema.
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <ctype.h>
32 #include "sqlite3.h"
34 static const char zHelp[] =
35 "Usage: %s COMMAND\n"
36 "Commands:\n"
37 " init Initialized the startup.db database file\n"
38 " run Run the startup performance test\n"
39 "Options:\n"
40 " --dbname NAME Set the name of the test database file\n"
41 " --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n"
42 " --stats Show statistics at the end\n"
43 /* TBD
44 " --journal M Set the journal_mode to M\n"
45 " --lookaside N SZ Configure lookaside for N slots of SZ bytes each\n"
46 " --mmap SZ MMAP the first SZ bytes of the database file\n"
47 " --multithread Set multithreaded mode\n"
48 " --nomemstat Disable memory statistics\n"
49 " --pagesize N Set the page size to N\n"
50 " --pcache N SZ Configure N pages of pagecache each of size SZ bytes\n"
51 " --serialized Set serialized threading mode\n"
52 " --singlethread Set single-threaded mode - disables all mutexing\n"
53 " --utf16be Set text encoding to UTF-16BE\n"
54 " --utf16le Set text encoding to UTF-16LE\n"
55 " --utf8 Set text encoding to UTF-8\n"
59 static void usage(const char *argv0){
60 printf(zHelp, argv0);
61 exit(1);
65 ** The test schema is derived from the Fossil repository for SQLite itself.
66 ** The schema covers the repository, the local checkout database, and
67 ** the global configuration database.
69 static const char zTestSchema[] =
70 "CREATE TABLE repo_blob(\n"
71 " rid INTEGER PRIMARY KEY,\n"
72 " rcvid INTEGER,\n"
73 " size INTEGER,\n"
74 " uuid TEXT UNIQUE NOT NULL,\n"
75 " content BLOB,\n"
76 " CHECK( length(uuid)>=40 AND rid>0 )\n"
77 ");\n"
78 "CREATE TABLE repo_delta(\n"
79 " rid INTEGER PRIMARY KEY,\n"
80 " srcid INTEGER NOT NULL REFERENCES blob\n"
81 ");\n"
82 "CREATE TABLE repo_rcvfrom(\n"
83 " rcvid INTEGER PRIMARY KEY,\n"
84 " uid INTEGER REFERENCES user,\n"
85 " mtime DATETIME,\n"
86 " nonce TEXT UNIQUE,\n"
87 " ipaddr TEXT\n"
88 ");\n"
89 "CREATE TABLE repo_private(rid INTEGER PRIMARY KEY);\n"
90 "CREATE TABLE repo_accesslog(\n"
91 " uname TEXT,\n"
92 " ipaddr TEXT,\n"
93 " success BOOLEAN,\n"
94 " mtime TIMESTAMP);\n"
95 "CREATE TABLE repo_user(\n"
96 " uid INTEGER PRIMARY KEY,\n"
97 " login TEXT UNIQUE,\n"
98 " pw TEXT,\n"
99 " cap TEXT,\n"
100 " cookie TEXT,\n"
101 " ipaddr TEXT,\n"
102 " cexpire DATETIME,\n"
103 " info TEXT,\n"
104 " mtime DATE,\n"
105 " photo BLOB\n"
106 ");\n"
107 "CREATE TABLE repo_reportfmt(\n"
108 " rn INTEGER PRIMARY KEY,\n"
109 " owner TEXT,\n"
110 " title TEXT UNIQUE,\n"
111 " mtime INTEGER,\n"
112 " cols TEXT,\n"
113 " sqlcode TEXT\n"
114 ");\n"
115 "CREATE TABLE repo_sqlite_stat2(tbl,idx,sampleno,sample);\n"
116 "CREATE TABLE repo_sqlite_stat1(tbl,idx,stat);\n"
117 "CREATE TABLE repo_sqlite_stat3(tbl,idx,neq,nlt,ndlt,sample);\n"
118 "CREATE TABLE repo_config(\n"
119 " name TEXT PRIMARY KEY NOT NULL,\n"
120 " value CLOB, mtime INTEGER,\n"
121 " CHECK( typeof(name)='text' AND length(name)>=1 )\n"
122 ") WITHOUT ROWID;\n"
123 "CREATE TABLE repo_shun(uuid PRIMARY KEY,\n"
124 " mtime INTEGER,\n"
125 " scom TEXT) WITHOUT ROWID;\n"
126 "CREATE TABLE repo_concealed(\n"
127 " hash TEXT PRIMARY KEY,\n"
128 " content TEXT\n"
129 ", mtime INTEGER) WITHOUT ROWID;\n"
130 "CREATE TABLE repo_admin_log(\n"
131 " id INTEGER PRIMARY KEY,\n"
132 " time INTEGER, -- Seconds since 1970\n"
133 " page TEXT, -- path of page\n"
134 " who TEXT, -- User who made the change\n"
135 " what TEXT -- What changed\n"
136 ");\n"
137 "CREATE TABLE repo_unversioned(\n"
138 " name TEXT PRIMARY KEY,\n"
139 " rcvid INTEGER,\n"
140 " mtime DATETIME,\n"
141 " hash TEXT,\n"
142 " sz INTEGER,\n"
143 " encoding INT,\n"
144 " content BLOB\n"
145 ") WITHOUT ROWID;\n"
146 "CREATE TABLE repo_subscriber(\n"
147 " subscriberId INTEGER PRIMARY KEY,\n"
148 " subscriberCode BLOB DEFAULT (randomblob(32)) UNIQUE,\n"
149 " semail TEXT UNIQUE COLLATE nocase,\n"
150 " suname TEXT,\n"
151 " sverified BOOLEAN DEFAULT true,\n"
152 " sdonotcall BOOLEAN,\n"
153 " sdigest BOOLEAN,\n"
154 " ssub TEXT,\n"
155 " sctime INTDATE,\n"
156 " mtime INTDATE,\n"
157 " smip TEXT\n"
158 ");\n"
159 "CREATE TABLE repo_pending_alert(\n"
160 " eventid TEXT PRIMARY KEY,\n"
161 " sentSep BOOLEAN DEFAULT false,\n"
162 " sentDigest BOOLEAN DEFAULT false\n"
163 ", sentMod BOOLEAN DEFAULT false) WITHOUT ROWID;\n"
164 "CREATE INDEX repo_delta_i1 ON repo_delta(srcid);\n"
165 "CREATE INDEX repo_blob_rcvid ON repo_blob(rcvid);\n"
166 "CREATE INDEX repo_subscriberUname\n"
167 " ON repo_subscriber(suname) WHERE suname IS NOT NULL;\n"
168 "CREATE VIEW repo_artifact(rid,rcvid,size,atype,srcid,hash,content) AS\n"
169 " SELECT blob.rid,rcvid,size,1,srcid,uuid,content\n"
170 " FROM repo_blob LEFT JOIN repo_delta ON (blob.rid=delta.rid);\n"
171 "CREATE TABLE repo_filename(\n"
172 " fnid INTEGER PRIMARY KEY,\n"
173 " name TEXT UNIQUE\n"
174 ");\n"
175 "CREATE TABLE repo_mlink(\n"
176 " mid INTEGER,\n"
177 " fid INTEGER,\n"
178 " pmid INTEGER,\n"
179 " pid INTEGER,\n"
180 " fnid INTEGER REFERENCES filename,\n"
181 " pfnid INTEGER,\n"
182 " mperm INTEGER,\n"
183 " isaux BOOLEAN DEFAULT 0\n"
184 ");\n"
185 "CREATE INDEX repo_mlink_i1 ON repo_mlink(mid);\n"
186 "CREATE INDEX repo_mlink_i2 ON repo_mlink(fnid);\n"
187 "CREATE INDEX repo_mlink_i3 ON repo_mlink(fid);\n"
188 "CREATE INDEX repo_mlink_i4 ON repo_mlink(pid);\n"
189 "CREATE TABLE repo_plink(\n"
190 " pid INTEGER REFERENCES blob,\n"
191 " cid INTEGER REFERENCES blob,\n"
192 " isprim BOOLEAN,\n"
193 " mtime DATETIME,\n"
194 " baseid INTEGER REFERENCES blob,\n"
195 " UNIQUE(pid, cid)\n"
196 ");\n"
197 "CREATE INDEX repo_plink_i2 ON repo_plink(cid,pid);\n"
198 "CREATE TABLE repo_leaf(rid INTEGER PRIMARY KEY);\n"
199 "CREATE TABLE repo_event(\n"
200 " type TEXT,\n"
201 " mtime DATETIME,\n"
202 " objid INTEGER PRIMARY KEY,\n"
203 " tagid INTEGER,\n"
204 " uid INTEGER REFERENCES user,\n"
205 " bgcolor TEXT,\n"
206 " euser TEXT,\n"
207 " user TEXT,\n"
208 " ecomment TEXT,\n"
209 " comment TEXT,\n"
210 " brief TEXT,\n"
211 " omtime DATETIME\n"
212 ");\n"
213 "CREATE INDEX repo_event_i1 ON repo_event(mtime);\n"
214 "CREATE TABLE repo_phantom(\n"
215 " rid INTEGER PRIMARY KEY\n"
216 ");\n"
217 "CREATE TABLE repo_orphan(\n"
218 " rid INTEGER PRIMARY KEY,\n"
219 " baseline INTEGER\n"
220 ");\n"
221 "CREATE INDEX repo_orphan_baseline ON repo_orphan(baseline);\n"
222 "CREATE TABLE repo_unclustered(\n"
223 " rid INTEGER PRIMARY KEY\n"
224 ");\n"
225 "CREATE TABLE repo_unsent(\n"
226 " rid INTEGER PRIMARY KEY\n"
227 ");\n"
228 "CREATE TABLE repo_tag(\n"
229 " tagid INTEGER PRIMARY KEY,\n"
230 " tagname TEXT UNIQUE\n"
231 ");\n"
232 "CREATE TABLE repo_tagxref(\n"
233 " tagid INTEGER REFERENCES tag,\n"
234 " tagtype INTEGER,\n"
235 " srcid INTEGER REFERENCES blob,\n"
236 " origid INTEGER REFERENCES blob,\n"
237 " value TEXT,\n"
238 " mtime TIMESTAMP,\n"
239 " rid INTEGER REFERENCE blob,\n"
240 " UNIQUE(rid, tagid)\n"
241 ");\n"
242 "CREATE INDEX repo_tagxref_i1 ON repo_tagxref(tagid, mtime);\n"
243 "CREATE TABLE repo_backlink(\n"
244 " target TEXT,\n"
245 " srctype INT,\n"
246 " srcid INT,\n"
247 " mtime TIMESTAMP,\n"
248 " UNIQUE(target, srctype, srcid)\n"
249 ");\n"
250 "CREATE INDEX repo_backlink_src ON repo_backlink(srcid, srctype);\n"
251 "CREATE TABLE repo_attachment(\n"
252 " attachid INTEGER PRIMARY KEY,\n"
253 " isLatest BOOLEAN DEFAULT 0,\n"
254 " mtime TIMESTAMP,\n"
255 " src TEXT,\n"
256 " target TEXT,\n"
257 " filename TEXT,\n"
258 " comment TEXT,\n"
259 " user TEXT\n"
260 ");\n"
261 "CREATE INDEX repo_attachment_idx1\n"
262 " ON repo_attachment(target, filename, mtime);\n"
263 "CREATE INDEX repo_attachment_idx2 ON repo_attachment(src);\n"
264 "CREATE TABLE repo_cherrypick(\n"
265 " parentid INT,\n"
266 " childid INT,\n"
267 " isExclude BOOLEAN DEFAULT false,\n"
268 " PRIMARY KEY(parentid, childid)\n"
269 ") WITHOUT ROWID;\n"
270 "CREATE INDEX repo_cherrypick_cid ON repo_cherrypick(childid);\n"
271 "CREATE TABLE repo_ticket(\n"
272 " -- Do not change any column that begins with tkt_\n"
273 " tkt_id INTEGER PRIMARY KEY,\n"
274 " tkt_uuid TEXT UNIQUE,\n"
275 " tkt_mtime DATE,\n"
276 " tkt_ctime DATE,\n"
277 " -- Add as many fields as required below this line\n"
278 " type TEXT,\n"
279 " status TEXT,\n"
280 " subsystem TEXT,\n"
281 " priority TEXT,\n"
282 " severity TEXT,\n"
283 " foundin TEXT,\n"
284 " private_contact TEXT,\n"
285 " resolution TEXT,\n"
286 " title TEXT,\n"
287 " comment TEXT\n"
288 ");\n"
289 "CREATE TABLE repo_ticketchng(\n"
290 " -- Do not change any column that begins with tkt_\n"
291 " tkt_id INTEGER REFERENCES ticket,\n"
292 " tkt_rid INTEGER REFERENCES blob,\n"
293 " tkt_mtime DATE,\n"
294 " -- Add as many fields as required below this line\n"
295 " login TEXT,\n"
296 " username TEXT,\n"
297 " mimetype TEXT,\n"
298 " icomment TEXT\n"
299 ");\n"
300 "CREATE INDEX repo_ticketchng_idx1 ON repo_ticketchng(tkt_id, tkt_mtime);\n"
301 "CREATE TRIGGER repo_alert_trigger1\n"
302 "AFTER INSERT ON repo_event BEGIN\n"
303 " INSERT INTO repo_pending_alert(eventid)\n"
304 " SELECT printf('%.1c%d',new.type,new.objid) WHERE true\n"
305 " ON CONFLICT(eventId) DO NOTHING;\n"
306 "END;\n"
307 "CREATE TABLE repo_vcache(\n"
308 " vid INTEGER, -- check-in ID\n"
309 " fname TEXT, -- filename\n"
310 " rid INTEGER, -- artifact ID\n"
311 " PRIMARY KEY(vid,fname)\n"
312 ") WITHOUT ROWID;\n"
313 "CREATE TABLE localdb_vvar(\n"
314 " name TEXT PRIMARY KEY NOT NULL,\n"
315 " value CLOB,\n"
316 " CHECK( typeof(name)='text' AND length(name)>=1 )\n"
317 ");\n"
318 "CREATE TABLE localdb_vfile(\n"
319 " id INTEGER PRIMARY KEY,\n"
320 " vid INTEGER REFERENCES blob,\n"
321 " chnged INT DEFAULT 0,\n"
322 " deleted BOOLEAN DEFAULT 0,\n"
323 " isexe BOOLEAN,\n"
324 " islink BOOLEAN,\n"
325 " rid INTEGER,\n"
326 " mrid INTEGER,\n"
327 " mtime INTEGER,\n"
328 " pathname TEXT,\n"
329 " origname TEXT, mhash,\n"
330 " UNIQUE(pathname,vid)\n"
331 ");\n"
332 "CREATE TABLE localdb_sqlite_stat1(tbl,idx,stat);\n"
333 "CREATE TABLE localdb_vcache(\n"
334 " vid INTEGER, -- check-in ID\n"
335 " fname TEXT, -- filename\n"
336 " rid INTEGER, -- artifact ID\n"
337 " PRIMARY KEY(vid,fname)\n"
338 ") WITHOUT ROWID;\n"
339 "CREATE TABLE localdb_stash(\n"
340 " stashid INTEGER PRIMARY KEY,\n"
341 " vid INTEGER,\n"
342 " hash TEXT,\n"
343 " comment TEXT,\n"
344 " ctime TIMESTAMP\n"
345 ");\n"
346 "CREATE TABLE localdb_stashfile(\n"
347 " stashid INTEGER REFERENCES stash,\n"
348 " isAdded BOOLEAN,\n"
349 " isRemoved BOOLEAN,\n"
350 " isExec BOOLEAN,\n"
351 " isLink BOOLEAN,\n"
352 " rid INTEGER,\n"
353 " hash TEXT,\n"
354 " origname TEXT,\n"
355 " newname TEXT,\n"
356 " delta BLOB,\n"
357 " PRIMARY KEY(newname, stashid)\n"
358 ");\n"
359 "CREATE TABLE localdb_vmerge(\n"
360 " id INTEGER REFERENCES vfile,\n"
361 " merge INTEGER,\n"
362 " mhash TEXT\n"
363 ");\n"
364 "CREATE UNIQUE INDEX localdb_vmergex1 ON localdb_vmerge(id,mhash);\n"
365 "CREATE TRIGGER localdb_vmerge_ck1 AFTER INSERT ON localdb_vmerge\n"
366 "WHEN new.mhash IS NULL BEGIN\n"
367 " SELECT raise(FAIL,\n"
368 " 'trying to update a newer checkout with an older version of Fossil');\n"
369 "END;\n"
370 "CREATE TABLE configdb_global_config(\n"
371 " name TEXT PRIMARY KEY,\n"
372 " value TEXT\n"
373 ");\n"
374 "CREATE TABLE configdb_sqlite_stat1(tbl,idx,stat);\n"
377 #ifdef __linux__
378 #include <sys/types.h>
379 #include <unistd.h>
382 ** Attempt to display I/O stats on Linux using /proc/PID/io
384 static void displayLinuxIoStats(FILE *out){
385 FILE *in;
386 char z[200];
387 sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
388 in = fopen(z, "rb");
389 if( in==0 ) return;
390 while( fgets(z, sizeof(z), in)!=0 ){
391 static const struct {
392 const char *zPattern;
393 const char *zDesc;
394 } aTrans[] = {
395 { "rchar: ", "Bytes received by read():" },
396 { "wchar: ", "Bytes sent to write():" },
397 { "syscr: ", "Read() system calls:" },
398 { "syscw: ", "Write() system calls:" },
399 { "read_bytes: ", "Bytes rcvd from storage:" },
400 { "write_bytes: ", "Bytes sent to storage:" },
401 { "cancelled_write_bytes: ", "Cancelled write bytes:" },
403 int i;
404 for(i=0; i<sizeof(aTrans)/sizeof(aTrans[0]); i++){
405 int n = (int)strlen(aTrans[i].zPattern);
406 if( strncmp(aTrans[i].zPattern, z, n)==0 ){
407 fprintf(out, "-- %-28s %s", aTrans[i].zDesc, &z[n]);
408 break;
412 fclose(in);
414 #endif
417 ** Return the value of a hexadecimal digit. Return -1 if the input
418 ** is not a hex digit.
420 static int hexDigitValue(char c){
421 if( c>='0' && c<='9' ) return c - '0';
422 if( c>='a' && c<='f' ) return c - 'a' + 10;
423 if( c>='A' && c<='F' ) return c - 'A' + 10;
424 return -1;
428 ** Interpret zArg as an integer value, possibly with suffixes.
430 static int integerValue(const char *zArg){
431 sqlite3_int64 v = 0;
432 static const struct { char *zSuffix; int iMult; } aMult[] = {
433 { "KiB", 1024 },
434 { "MiB", 1024*1024 },
435 { "GiB", 1024*1024*1024 },
436 { "KB", 1000 },
437 { "MB", 1000000 },
438 { "GB", 1000000000 },
439 { "K", 1000 },
440 { "M", 1000000 },
441 { "G", 1000000000 },
443 int i;
444 int isNeg = 0;
445 if( zArg[0]=='-' ){
446 isNeg = 1;
447 zArg++;
448 }else if( zArg[0]=='+' ){
449 zArg++;
451 if( zArg[0]=='0' && zArg[1]=='x' ){
452 int x;
453 zArg += 2;
454 while( (x = hexDigitValue(zArg[0]))>=0 ){
455 v = (v<<4) + x;
456 zArg++;
458 }else{
459 while( isdigit(zArg[0]) ){
460 v = v*10 + zArg[0] - '0';
461 zArg++;
464 for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){
465 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
466 v *= aMult[i].iMult;
467 break;
470 if( v>0x7fffffff ){
471 printf("ERROR: parameter too large - max 2147483648\n");
472 exit(1);
474 return (int)(isNeg? -v : v);
478 int main(int argc, char **argv){
479 const char *zCmd = 0;
480 int i;
481 int bAutovac = 0;
482 int showStats = 0;
483 const char *zDbName = "./startup.db";
484 int nHeap = 0;
485 int mnHeap = 0;
487 for(i=1; i<argc; i++){
488 const char *z = argv[i];
489 if( z[0]!='-' ){
490 if( zCmd ){
491 usage(argv[0]);
493 zCmd = z;
494 continue;
496 if( z[1]=='-' ) z++;
497 if( strcmp(z, "-autovacuum")==0 ){
498 bAutovac = 1;
499 }else
500 if( strcmp(z, "-dbname")==0 ){
501 if( i==argc-1 ){
502 printf("ERROR: missing argument on \"%s\"\n", argv[0]);
503 exit(1);
505 zDbName = argv[++i];
506 }else
507 if( strcmp(z,"-heap")==0 ){
508 if( i>=argc-2 ){
509 printf("ERROR: missing arguments on %s\n", argv[i]);
510 exit(1);
512 nHeap = integerValue(argv[i+1]);
513 mnHeap = integerValue(argv[i+2]);
514 i += 2;
515 }else
516 if( strcmp(z,"-stats")==0 ){
517 showStats = 1;
518 }else
520 printf("ERROR: unknown option \"%s\"\n", argv[i]);
521 usage(argv[0]);
524 if( zCmd==0 ){
525 printf("ERROR: no COMMAND specified\n");
526 usage(argv[0]);
528 if( strcmp(zCmd, "run")==0 ){
529 sqlite3 *db;
530 int rc;
531 char *zErr = 0;
532 void *pHeap = 0;
533 if( nHeap>0 ){
534 pHeap = malloc( nHeap );
535 if( pHeap==0 ){
536 printf("ERROR: cannot allocate %d-byte heap\n", nHeap);
537 exit(1);
539 rc = sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap);
540 if( rc ){
541 printf("ERROR: heap configuration failed: %d\n", rc);
542 exit(1);
545 rc = sqlite3_open(zDbName, &db);
546 if( rc ){
547 printf("SQLite error: %s\n", sqlite3_errmsg(db));
548 }else{
549 sqlite3_exec(db, "PRAGMA synchronous", 0, 0, &zErr);
551 if( zErr ){
552 printf("ERROR: %s\n", zErr);
553 sqlite3_free(zErr);
555 if( showStats ){
556 int iCur, iHi;
557 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHi, 0);
558 printf("-- Lookaside Slots Used: %d (max %d)\n", iCur,iHi);
559 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHi, 0);
560 printf("-- Successful lookasides: %d\n", iHi);
561 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur,&iHi,0);
562 printf("-- Lookaside size faults: %d\n", iHi);
563 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur,&iHi,0);
564 printf("-- Lookaside OOM faults: %d\n", iHi);
565 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHi, 0);
566 printf("-- Pager Heap Usage: %d bytes\n", iCur);
567 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHi, 1);
568 printf("-- Page cache hits: %d\n", iCur);
569 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHi, 1);
570 printf("-- Page cache misses: %d\n", iCur);
571 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHi, 1);
572 printf("-- Page cache writes: %d\n", iCur);
573 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHi, 0);
574 printf("-- Schema Heap Usage: %d bytes\n", iCur);
575 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHi, 0);
576 printf("-- Statement Heap Usage: %d bytes\n", iCur);
578 sqlite3_close(db);
579 free(pHeap);
580 /* Global memory usage statistics printed after the database connection
581 ** has closed. Memory usage should be zero at this point. */
582 if( showStats ){
583 int iCur, iHi;
584 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHi, 0);
585 printf("-- Memory Used (bytes): %d (max %d)\n", iCur,iHi);
586 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHi, 0);
587 printf("-- Outstanding Allocations: %d (max %d)\n", iCur,iHi);
588 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHi, 0);
589 printf("-- Pcache Overflow Bytes: %d (max %d)\n", iCur,iHi);
590 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHi, 0);
591 printf("-- Largest Allocation: %d bytes\n",iHi);
592 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHi, 0);
593 printf("-- Largest Pcache Allocation: %d bytes\n",iHi);
594 #ifdef __linux__
595 displayLinuxIoStats(stdout);
596 #endif
598 return 0;
600 if( strcmp(zCmd, "init")==0 ){
601 sqlite3 *db;
602 char *zAux;
603 char *zErr = 0;
604 int rc;
605 unlink(zDbName);
606 zAux = sqlite3_mprintf("%s-journal", zDbName);
607 unlink(zAux);
608 sqlite3_free(zAux);
609 zAux = sqlite3_mprintf("%s-wal", zDbName);
610 unlink(zAux);
611 sqlite3_free(zAux);
612 rc = sqlite3_open(zDbName, &db);
613 if( rc ){
614 printf("SQLite error: %s\n", sqlite3_errmsg(db));
615 }else{
616 sqlite3_exec(db, "BEGIN", 0, 0, 0);
617 sqlite3_exec(db, zTestSchema, 0, 0, &zErr);
618 sqlite3_exec(db, "COMMIT", 0, 0, 0);
620 if( zErr ){
621 printf("ERROR: %s\n", zErr);
622 sqlite3_free(zErr);
624 sqlite3_close(db);
625 return 0;