Annotation of embedaddon/sqlite3/test/tt3_checkpoint.c, revision 1.1

1.1     ! misho       1: /*
        !             2: ** 2001 September 15
        !             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.
        !            10: **
        !            11: *************************************************************************
        !            12: ** This file is part of the test program "threadtest3". Despite being a C
        !            13: ** file it is not compiled separately, but included by threadtest3.c using
        !            14: ** the #include directive normally used with header files.
        !            15: **
        !            16: ** This file contains the implementation of test cases:
        !            17: **
        !            18: **     checkpoint_starvation_1
        !            19: **     checkpoint_starvation_2
        !            20: */
        !            21: 
        !            22: /*
        !            23: ** Both test cases involve 1 writer/checkpointer thread and N reader threads.
        !            24: ** 
        !            25: ** Each reader thread performs a series of read transactions, one after 
        !            26: ** another. Each read transaction lasts for 100 ms.
        !            27: **
        !            28: ** The writer writes transactions as fast as possible. It uses a callback
        !            29: ** registered with sqlite3_wal_hook() to try to keep the WAL-size limited to 
        !            30: ** around 50 pages.
        !            31: **
        !            32: ** In test case checkpoint_starvation_1, the auto-checkpoint uses 
        !            33: ** SQLITE_CHECKPOINT_PASSIVE. In checkpoint_starvation_2, it uses RESTART.
        !            34: ** The expectation is that in the first case the WAL file will grow very 
        !            35: ** large, and in the second will be limited to the 50 pages or thereabouts.
        !            36: ** However, the overall transaction throughput will be lower for 
        !            37: ** checkpoint_starvation_2, as every checkpoint will block for up to 200 ms
        !            38: ** waiting for readers to clear.
        !            39: */
        !            40: 
        !            41: /* Frame limit used by the WAL hook for these tests. */
        !            42: #define CHECKPOINT_STARVATION_FRAMELIMIT 50
        !            43: 
        !            44: /* Duration in ms of each read transaction */
        !            45: #define CHECKPOINT_STARVATION_READMS    100
        !            46: 
        !            47: struct CheckpointStarvationCtx {
        !            48:   int eMode;
        !            49:   int nMaxFrame;
        !            50: };
        !            51: typedef struct CheckpointStarvationCtx CheckpointStarvationCtx;
        !            52: 
        !            53: static int checkpoint_starvation_walhook(
        !            54:   void *pCtx, 
        !            55:   sqlite3 *db, 
        !            56:   const char *zDb, 
        !            57:   int nFrame
        !            58: ){
        !            59:   CheckpointStarvationCtx *p = (CheckpointStarvationCtx *)pCtx;
        !            60:   if( nFrame>p->nMaxFrame ){
        !            61:     p->nMaxFrame = nFrame;
        !            62:   }
        !            63:   if( nFrame>=CHECKPOINT_STARVATION_FRAMELIMIT ){
        !            64:     sqlite3_wal_checkpoint_v2(db, zDb, p->eMode, 0, 0);
        !            65:   }
        !            66:   return SQLITE_OK;
        !            67: }
        !            68: 
        !            69: static char *checkpoint_starvation_reader(int iTid, int iArg){
        !            70:   Error err = {0};
        !            71:   Sqlite db = {0};
        !            72: 
        !            73:   opendb(&err, &db, "test.db", 0);
        !            74:   while( !timetostop(&err) ){
        !            75:     i64 iCount1, iCount2;
        !            76:     sql_script(&err, &db, "BEGIN");
        !            77:     iCount1 = execsql_i64(&err, &db, "SELECT count(x) FROM t1");
        !            78:     usleep(CHECKPOINT_STARVATION_READMS*1000);
        !            79:     iCount2 = execsql_i64(&err, &db, "SELECT count(x) FROM t1");
        !            80:     sql_script(&err, &db, "COMMIT");
        !            81: 
        !            82:     if( iCount1!=iCount2 ){
        !            83:       test_error(&err, "Isolation failure - %lld %lld", iCount1, iCount2);
        !            84:     }
        !            85:   }
        !            86:   closedb(&err, &db);
        !            87: 
        !            88:   print_and_free_err(&err);
        !            89:   return 0;
        !            90: }
        !            91: 
        !            92: static void checkpoint_starvation_main(int nMs, CheckpointStarvationCtx *p){
        !            93:   Error err = {0};
        !            94:   Sqlite db = {0};
        !            95:   Threadset threads = {0};
        !            96:   int nInsert = 0;
        !            97:   int i;
        !            98: 
        !            99:   opendb(&err, &db, "test.db", 1);
        !           100:   sql_script(&err, &db, 
        !           101:       "PRAGMA page_size = 1024;"
        !           102:       "PRAGMA journal_mode = WAL;"
        !           103:       "CREATE TABLE t1(x);"
        !           104:   );
        !           105: 
        !           106:   setstoptime(&err, nMs);
        !           107: 
        !           108:   for(i=0; i<4; i++){
        !           109:     launch_thread(&err, &threads, checkpoint_starvation_reader, 0);
        !           110:     usleep(CHECKPOINT_STARVATION_READMS*1000/4);
        !           111:   }
        !           112: 
        !           113:   sqlite3_wal_hook(db.db, checkpoint_starvation_walhook, (void *)p);
        !           114:   while( !timetostop(&err) ){
        !           115:     sql_script(&err, &db, "INSERT INTO t1 VALUES(randomblob(1200))");
        !           116:     nInsert++;
        !           117:   }
        !           118: 
        !           119:   printf(" Checkpoint mode  : %s\n",
        !           120:       p->eMode==SQLITE_CHECKPOINT_PASSIVE ? "PASSIVE" : "RESTART"
        !           121:   );
        !           122:   printf(" Peak WAL         : %d frames\n", p->nMaxFrame);
        !           123:   printf(" Transaction count: %d transactions\n", nInsert);
        !           124: 
        !           125:   join_all_threads(&err, &threads);
        !           126:   closedb(&err, &db);
        !           127:   print_and_free_err(&err);
        !           128: }
        !           129: 
        !           130: static void checkpoint_starvation_1(int nMs){
        !           131:   Error err = {0};
        !           132:   CheckpointStarvationCtx ctx = { SQLITE_CHECKPOINT_PASSIVE, 0 };
        !           133:   checkpoint_starvation_main(nMs, &ctx);
        !           134:   if( ctx.nMaxFrame<(CHECKPOINT_STARVATION_FRAMELIMIT*10) ){
        !           135:     test_error(&err, "WAL failed to grow - %d frames", ctx.nMaxFrame);
        !           136:   }
        !           137:   print_and_free_err(&err);
        !           138: }
        !           139: 
        !           140: static void checkpoint_starvation_2(int nMs){
        !           141:   Error err = {0};
        !           142:   CheckpointStarvationCtx ctx = { SQLITE_CHECKPOINT_RESTART, 0 };
        !           143:   checkpoint_starvation_main(nMs, &ctx);
        !           144:   if( ctx.nMaxFrame>CHECKPOINT_STARVATION_FRAMELIMIT+10 ){
        !           145:     test_error(&err, "WAL grew too large - %d frames", ctx.nMaxFrame);
        !           146:   }
        !           147:   print_and_free_err(&err);
        !           148: }
        !           149: 
        !           150: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>