dbstatus.test 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. # 2010 March 10
  2. #
  3. # The author disclaims copyright to this source code. In place of
  4. # a legal notice, here is a blessing:
  5. #
  6. # May you do good and not evil.
  7. # May you find forgiveness for yourself and forgive others.
  8. # May you share freely, never taking more than you give.
  9. #
  10. #***********************************************************************
  11. #
  12. # Tests for the sqlite3_db_status() function
  13. #
  14. set testdir [file dirname $argv0]
  15. source $testdir/tester.tcl
  16. ifcapable !compound {
  17. finish_test
  18. return
  19. }
  20. # Memory statistics must be enabled for this test.
  21. db close
  22. sqlite3_shutdown
  23. sqlite3_config_memstatus 1
  24. sqlite3_initialize
  25. sqlite3 db test.db
  26. # Make sure sqlite3_db_config() and sqlite3_db_status are working.
  27. #
  28. unset -nocomplain PAGESZ
  29. unset -nocomplain BASESZ
  30. do_test dbstatus-1.1 {
  31. db close
  32. sqlite3 db :memory:
  33. db eval {
  34. CREATE TABLE t1(x);
  35. }
  36. set sz1 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_CACHE_USED 0] 1]
  37. db eval {
  38. CREATE TABLE t2(y);
  39. }
  40. set sz2 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_CACHE_USED 0] 1]
  41. set ::PAGESZ [expr {$sz2-$sz1}]
  42. set ::BASESZ [expr {$sz1-$::PAGESZ}]
  43. expr {$::PAGESZ>1024 && $::PAGESZ<1300}
  44. } {1}
  45. do_test dbstatus-1.2 {
  46. db eval {
  47. INSERT INTO t1 VALUES(zeroblob(9000));
  48. }
  49. lindex [sqlite3_db_status db SQLITE_DBSTATUS_CACHE_USED 0] 1
  50. } [expr {$BASESZ + 10*$PAGESZ}]
  51. proc lookaside {db} {
  52. expr { $::lookaside_buffer_size *
  53. [lindex [sqlite3_db_status $db SQLITE_DBSTATUS_LOOKASIDE_USED 0] 1]
  54. }
  55. }
  56. ifcapable stat4||stat3 {
  57. set STAT3 1
  58. } else {
  59. set STAT3 0
  60. }
  61. ifcapable malloc_usable_size {
  62. finish_test
  63. return
  64. }
  65. #---------------------------------------------------------------------------
  66. # Run the dbstatus-2 and dbstatus-3 tests with several of different
  67. # lookaside buffer sizes.
  68. #
  69. foreach ::lookaside_buffer_size {0 64 120} {
  70. # Do not run any of these tests if there is SQL configured to run
  71. # as part of the [sqlite3] command. This prevents the script from
  72. # configuring the size of the lookaside buffer after [sqlite3] has
  73. # returned.
  74. if {[presql] != ""} break
  75. #-------------------------------------------------------------------------
  76. # Tests for SQLITE_DBSTATUS_SCHEMA_USED.
  77. #
  78. # Each test in the following block works as follows. Each test uses a
  79. # different database schema.
  80. #
  81. # 1. Open a connection to an empty database. Disable statement caching.
  82. #
  83. # 2. Execute the SQL to create the database schema. Measure the total
  84. # heap and lookaside memory allocated by SQLite, and the memory
  85. # allocated for the database schema according to sqlite3_db_status().
  86. #
  87. # 3. Drop all tables in the database schema. Measure the total memory
  88. # and the schema memory again.
  89. #
  90. # 4. Repeat step 2.
  91. #
  92. # 5. Repeat step 3.
  93. #
  94. # Then test that:
  95. #
  96. # a) The difference in schema memory quantities in steps 2 and 3 is the
  97. # same as the difference in total memory in steps 2 and 3.
  98. #
  99. # b) Step 4 reports the same amount of schema and total memory used as
  100. # in step 2.
  101. #
  102. # c) Step 5 reports the same amount of schema and total memory used as
  103. # in step 3.
  104. #
  105. foreach {tn schema} {
  106. 1 { CREATE TABLE t1(a, b) }
  107. 2 { CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1, c UNIQUE) }
  108. 3 {
  109. CREATE TABLE t1(a, b);
  110. CREATE INDEX i1 ON t1(a, b);
  111. }
  112. 4 {
  113. CREATE TABLE t1(a, b);
  114. CREATE TABLE t2(c, d);
  115. CREATE TRIGGER AFTER INSERT ON t1 BEGIN
  116. INSERT INTO t2 VALUES(new.a, new.b);
  117. SELECT * FROM t1, t2 WHERE a=c AND b=d GROUP BY b HAVING a>5 ORDER BY a;
  118. END;
  119. }
  120. 5 {
  121. CREATE TABLE t1(a, b);
  122. CREATE TABLE t2(c, d);
  123. CREATE VIEW v1 AS SELECT * FROM t1 UNION SELECT * FROM t2;
  124. }
  125. 6y {
  126. CREATE TABLE t1(a, b);
  127. CREATE INDEX i1 ON t1(a);
  128. CREATE INDEX i2 ON t1(a,b);
  129. CREATE INDEX i3 ON t1(b,b);
  130. INSERT INTO t1 VALUES(randomblob(20), randomblob(25));
  131. INSERT INTO t1 SELECT randomblob(20), randomblob(25) FROM t1;
  132. INSERT INTO t1 SELECT randomblob(20), randomblob(25) FROM t1;
  133. INSERT INTO t1 SELECT randomblob(20), randomblob(25) FROM t1;
  134. ANALYZE;
  135. }
  136. 7 {
  137. CREATE TABLE t1(a, b);
  138. CREATE TABLE t2(c, d);
  139. CREATE VIEW v1 AS
  140. SELECT * FROM t1
  141. UNION
  142. SELECT * FROM t2
  143. UNION ALL
  144. SELECT c||b, d||a FROM t2 LEFT OUTER JOIN t1 GROUP BY c, d
  145. ORDER BY 1, 2
  146. ;
  147. CREATE TRIGGER tr1 INSTEAD OF INSERT ON v1 BEGIN
  148. SELECT * FROM v1;
  149. UPDATE t1 SET a=5, b=(SELECT c FROM t2);
  150. END;
  151. SELECT * FROM v1;
  152. }
  153. 8x {
  154. CREATE TABLE t1(a, b, UNIQUE(a, b));
  155. CREATE VIRTUAL TABLE t2 USING echo(t1);
  156. }
  157. } {
  158. set tn "$::lookaside_buffer_size-$tn"
  159. # Step 1.
  160. db close
  161. forcedelete test.db
  162. sqlite3 db test.db
  163. sqlite3_db_config_lookaside db 0 $::lookaside_buffer_size 500
  164. db cache size 0
  165. catch { register_echo_module db }
  166. ifcapable !vtab { if {[string match *x $tn]} continue }
  167. # Step 2.
  168. execsql $schema
  169. set nAlloc1 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
  170. incr nAlloc1 [lookaside db]
  171. set nSchema1 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_SCHEMA_USED 0] 1]
  172. # Step 3.
  173. drop_all_tables
  174. set nAlloc2 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
  175. incr nAlloc2 [lookaside db]
  176. set nSchema2 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_SCHEMA_USED 0] 1]
  177. # Step 4.
  178. execsql $schema
  179. set nAlloc3 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
  180. incr nAlloc3 [lookaside db]
  181. set nSchema3 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_SCHEMA_USED 0] 1]
  182. # Step 5.
  183. drop_all_tables
  184. set nAlloc4 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
  185. incr nAlloc4 [lookaside db]
  186. set nSchema4 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_SCHEMA_USED 0] 1]
  187. set nFree [expr {$nAlloc1-$nAlloc2}]
  188. # Tests for which the test name ends in an "x" report slightly less
  189. # memory than is actually freed when all schema items are finalized.
  190. # This is because memory allocated by virtual table implementations
  191. # for any reason is not counted as "schema memory".
  192. #
  193. # Additionally, in auto-vacuum mode, dropping tables and indexes causes
  194. # the page-cache to shrink. So the amount of memory freed is always
  195. # much greater than just that reported by DBSTATUS_SCHEMA_USED in this
  196. # case.
  197. #
  198. # Some of the memory used for sqlite_stat4 is unaccounted for by
  199. # dbstatus.
  200. #
  201. # Finally, on osx the estimate of memory used by the schema may be
  202. # slightly low.
  203. #
  204. if {[string match *x $tn] || $AUTOVACUUM
  205. || ([string match *y $tn] && $STAT3)
  206. || ($::tcl_platform(os) == "Darwin")
  207. } {
  208. do_test dbstatus-2.$tn.ax { expr {($nSchema1-$nSchema2)<=$nFree} } 1
  209. } else {
  210. do_test dbstatus-2.$tn.a { expr {$nSchema1-$nSchema2} } $nFree
  211. }
  212. do_test dbstatus-2.$tn.b { list $nAlloc1 $nSchema1 } "$nAlloc3 $nSchema3"
  213. do_test dbstatus-2.$tn.c { list $nAlloc2 $nSchema2 } "$nAlloc4 $nSchema4"
  214. }
  215. #-------------------------------------------------------------------------
  216. # Tests for SQLITE_DBSTATUS_STMT_USED.
  217. #
  218. # Each test in the following block works as follows. Each test uses a
  219. # different database schema.
  220. #
  221. # 1. Open a connection to an empty database. Initialized the database
  222. # schema.
  223. #
  224. # 2. Prepare a bunch of SQL statements. Measure the total heap and
  225. # lookaside memory allocated by SQLite, and the memory allocated
  226. # for the prepared statements according to sqlite3_db_status().
  227. #
  228. # 3. Finalize all prepared statements Measure the total memory
  229. # and the prepared statement memory again.
  230. #
  231. # 4. Repeat step 2.
  232. #
  233. # 5. Repeat step 3.
  234. #
  235. # Then test that:
  236. #
  237. # a) The difference in schema memory quantities in steps 2 and 3 is the
  238. # same as the difference in total memory in steps 2 and 3.
  239. #
  240. # b) Step 4 reports the same amount of schema and total memory used as
  241. # in step 2.
  242. #
  243. # c) Step 5 reports the same amount of schema and total memory used as
  244. # in step 3.
  245. #
  246. foreach {tn schema statements} {
  247. 1 { CREATE TABLE t1(a, b) } {
  248. SELECT * FROM t1;
  249. INSERT INTO t1 VALUES(1, 2);
  250. INSERT INTO t1 SELECT * FROM t1;
  251. UPDATE t1 SET a=5;
  252. DELETE FROM t1;
  253. }
  254. 2 {
  255. PRAGMA recursive_triggers = 1;
  256. CREATE TABLE t1(a, b);
  257. CREATE TRIGGER tr1 AFTER INSERT ON t1 WHEN (new.a>0) BEGIN
  258. INSERT INTO t1 VALUES(new.a-1, new.b);
  259. END;
  260. } {
  261. INSERT INTO t1 VALUES(5, 'x');
  262. }
  263. 3 {
  264. PRAGMA recursive_triggers = 1;
  265. CREATE TABLE t1(a, b);
  266. CREATE TABLE t2(a, b);
  267. CREATE TRIGGER tr1 AFTER INSERT ON t1 WHEN (new.a>0) BEGIN
  268. INSERT INTO t2 VALUES(new.a-1, new.b);
  269. END;
  270. CREATE TRIGGER tr2 AFTER INSERT ON t1 WHEN (new.a>0) BEGIN
  271. INSERT INTO t1 VALUES(new.a-1, new.b);
  272. END;
  273. } {
  274. INSERT INTO t1 VALUES(10, 'x');
  275. }
  276. 4 {
  277. CREATE TABLE t1(a, b);
  278. } {
  279. SELECT count(*) FROM t1 WHERE upper(a)='ABC';
  280. }
  281. 5x {
  282. CREATE TABLE t1(a, b UNIQUE);
  283. CREATE VIRTUAL TABLE t2 USING echo(t1);
  284. } {
  285. SELECT count(*) FROM t2;
  286. SELECT * FROM t2 WHERE b>5;
  287. SELECT * FROM t2 WHERE b='abcdefg';
  288. }
  289. } {
  290. set tn "$::lookaside_buffer_size-$tn"
  291. # Step 1.
  292. db close
  293. forcedelete test.db
  294. sqlite3 db test.db
  295. sqlite3_db_config_lookaside db 0 $::lookaside_buffer_size 500
  296. db cache size 1000
  297. catch { register_echo_module db }
  298. ifcapable !vtab { if {[string match *x $tn]} continue }
  299. execsql $schema
  300. db cache flush
  301. # Step 2.
  302. execsql $statements
  303. set nAlloc1 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
  304. incr nAlloc1 [lookaside db]
  305. set nStmt1 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_STMT_USED 0] 1]
  306. execsql $statements
  307. # Step 3.
  308. db cache flush
  309. set nAlloc2 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
  310. incr nAlloc2 [lookaside db]
  311. set nStmt2 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_STMT_USED 0] 1]
  312. # Step 3.
  313. execsql $statements
  314. set nAlloc3 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
  315. incr nAlloc3 [lookaside db]
  316. set nStmt3 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_STMT_USED 0] 1]
  317. execsql $statements
  318. # Step 4.
  319. db cache flush
  320. set nAlloc4 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
  321. incr nAlloc4 [lookaside db]
  322. set nStmt4 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_STMT_USED 0] 1]
  323. set nFree [expr {$nAlloc1-$nAlloc2}]
  324. do_test dbstatus-3.$tn.a { expr $nStmt2 } {0}
  325. # Tests for which the test name ends in an "x" report slightly less
  326. # memory than is actually freed when all statements are finalized.
  327. # This is because a small amount of memory allocated by a virtual table
  328. # implementation using sqlite3_mprintf() is technically considered
  329. # external and so is not counted as "statement memory".
  330. #
  331. #puts "$nStmt1 $nFree"
  332. if {[string match *x $tn]} {
  333. do_test dbstatus-3.$tn.bx { expr $nStmt1<=$nFree } {1}
  334. } else {
  335. do_test dbstatus-3.$tn.b { expr $nStmt1==$nFree } {1}
  336. }
  337. do_test dbstatus-3.$tn.c { list $nAlloc1 $nStmt1 } [list $nAlloc3 $nStmt3]
  338. do_test dbstatus-3.$tn.d { list $nAlloc2 $nStmt2 } [list $nAlloc4 $nStmt4]
  339. }
  340. }
  341. finish_test