sqlite增量真空仅删除一个免费页面

时间:2018-12-12 15:58:28

标签: sqlite vacuum autovacuum

我将我的sqlite数据库的auto_vacuum PRAGMA的值更改为INCREMENTAL。当我通过“用于SQlite的数据库浏览器”应用程序运行PRAGMA incremental_vacuum;时,它将释放free_list中的所有页面。 但是,当我使用C#中的任何SQLite库(例如Microsoft.Data.SQLite)运行同一条语句时,它仅从free_list

中释放一页

我通过在运行free_list语句之前和之后运行PRAGMA freelist_count来获取当前PRAGMA incremental_vacuum中的数字来进行验证。

我还尝试将不同的参数传递给incremental_vacuum杂注,例如PRAGMA incremental_vacuum(100),但仍只释放一页。

如果我在这里做错了什么请让我。

谢谢!

1 个答案:

答案 0 :(得分:0)

如果忽略了sqlite3_step()的结果,就会发生这种情况。如果返回SQLITE_ROW,则代码无法像返回SQLITE_DONE一样起作用。必须一直调用sqlite3_step()直到查询完成:不管是否是编译指示,查询都是一个查询,直到SQLITE_DONE :)才完成。碰巧一次删除一页:

bool do_incremental_vacuum(sqlite3 *db) {
   sqlite3_stmt *stmt = nullptr;
   auto rc = sqlite3_prepare_v2(db, "pragma freelist_count;", -1, &stmt);
   if (rc != SQLITE_OK) return false;
   rc = sqlite3_step(stmt);
   if (rc != SQLITE_DONE && rc != SQLITE_ROW) return false;
   auto freelist_count = sqlite3_column_int64(stmt, 0);
   rc = sqlite3_errcode(db);
   if (rc != SQLITE_OK && rc != SQLITE_DONE && rc != SQLITE_ROW) return false;
   std::cout << "There are " << freelist_count << " pages in the free list." << std::endl;

   rc = sqlite3_prepare_v2(db, "pragma incremental_vacuum;", -1, &stmt, nullptr);
   uint64_t pages = 0;
   if (rc != SQLITE_OK) return false;
   do {
      rc = sqlite3_step(stmt);
      if (rc == SQLITE_ROW) ++ pages;
   } while (rc == SQLITE_ROW);
   if (rc != SQLITE_DONE) return false;

   std::cout << "Freed " << pages << " pages" << std::endl;
   return true;
}