2

我已将我的 sqlite 数据库的 auto_vacuum PRAGMA 的值更改为 INCREMENTAL。当我PRAGMA incremental_vacuum;通过“DB Browser for SQlite”应用程序运行时,它会释放free_list. 但是,当我使用 C# 中的任何 SQLite 库(例如Microsoft.Data.SQLite)运行相同的语句时,它只会从free_list

我通过在运行语句之前和之后运行来获取当前的数字来验证free_list这一点PRAGMA freelist_countPRAGMA incremental_vacuum

此外,我尝试将不同的参数传递给incremental_vacuumpragma,例如PRAGMA incremental_vacuum(100),但它仍然只会释放一页。

如果我在这里做错了什么,请告诉我。

提前致谢!

4

1 回答 1

1

如果忽略来自 的结果,就会发生这种情况sqlite3_step()。如果它返回SQLITE_ROW,则代码不能像已返回一样运行SQLITE_DONE。必须一直调用sqlite3_step(),直到查询完成:pragma 与否,查询就是查询,直到它完成,嗯,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;
}
于 2019-06-02T03:30:05.200 回答