FlashDB之KVDB的GC过程实验

2024年6月6日星期四

以写入一条boot_count为例。boot_count每次值累加1.KV名不变。相当于每次把上一次的状态置删除,然后写入新的一条。

整条KV长度56(0x38)字节。

为了方便查看,数据库开始地址修改为0x20000,分配4个扇区。

[D/FAL] (fal_flash_init:47) Flash device |             stm32_onchip | addr: 0x08000000 | len: 0x00040000 | blk_size: 0x00000800 |initialized finish.

[32;22m[I/FAL] ==================== FAL partition table ====================[0m

[32;22m[I/FAL] | name      | flash_dev    |   offset   |    length  |[0m

[32;22m[I/FAL] -------------------------------------------------------------[0m

[32;22m[I/FAL] | fdb_tsdb1 | stm32_onchip | 0x0001a000 | 0x00002000 |[0m

[32;22m[I/FAL] | fdb_kvdb1 | stm32_onchip | 0x00020000 | 0x00002000 |[0m

[32;22m[I/FAL] =============================================================[0m

[32;22m[I/FAL] Flash Abstraction Layer (V0.5.99) initialize success.[0m

[FlashDB][kv][env][fdb_kvdb1] (..\..\..\src\fdb_kvdb.c:1777) The oldest addr is @0x00000000

[FlashDB][kv][env][fdb_kvdb1] (..\..\..\src\fdb_kvdb.c:1793) KVDB size is 8192 bytes.

[FlashDB][kv][env][fdb_kvdb1] Sector header info is incorrect. Auto format this sector (0x00000000).

[FlashDB][kv][env][fdb_kvdb1] Sector header info is incorrect. Auto format this sector (0x00000800).

[FlashDB][kv][env][fdb_kvdb1] Sector header info is incorrect. Auto format this sector (0x00001000).

[FlashDB][kv][env][fdb_kvdb1] Sector header info is incorrect. Auto format this sector (0x00001800).

[FlashDB][kv][env][fdb_kvdb1] All sector header is incorrect. Set it to default.

[FlashDB] FlashDB V2.1.0 is initialize success.

[FlashDB] You can get the latest version on https://github.com/armink/FlashDB .

empty_kV值为0x748。

0x2748位置写Val:28,此时还余0xB0字节。

0x38+0x24+0x40=0x9C。0xB0大于0x9C此次还能写入0扇区。写入后,empty_kV值为0x780。

0x2780位置写Val:29,此时还余0x80字节。

0x38+0x24+0x40=0x9C。0x80小于0x9C此时0扇区写不下。

//分配KV空间

static uint32_t alloc_kv(fdb_kvdb_t db, kv_sec_info_t sector, size_t kv_size)

{

    uint32_t empty_kv = FAILED_ADDR;

    size_t empty_sector = 0, using_sector = 0;

    struct alloc_kv_cb_args arg = {db, kv_size, &empty_kv};

    /* sector status statistics 扇区状态统计,统计使用的扇区和空扇区数量*/

    if (using_sector > 0) {

        /* alloc the KV from the using status sector first 首先从使用状态扇区分配KV*/

        sector_iterator(db, sector, FDB_SECTOR_STORE_USING, &arg, NULL, alloc_kv_cb, true);

    }

    if (empty_sector > 0 && empty_kv == FAILED_ADDR) {

        if (empty_sector > FDB_GC_EMPTY_SEC_THRESHOLD || db->gc_request) {//1个扇区写不下了,转下一个空扇区

            sector_iterator(db, sector, FDB_SECTOR_STORE_EMPTY, &arg, NULL, alloc_kv_cb, true);

        } else {

            /* no space for new KV now will GC and retry      现在没有空间给新的KV,将GC并重试*/

            FDB_DEBUG("Trigger a GC check after alloc KV failed.\n");

            db->gc_request = true;

        }

    }

    return empty_kv;

}

当一个扇区没空间了则执行

sector_iterator(db, sector, FDB_SECTOR_STORE_EMPTY, &arg, NULL, alloc_kv_cb, true);

查找到最近的一个空扇区。

并读取Flash下一扇区状态信息,计算出empty_kv,remain更新到扇区缓存表中。

[FlashDB][sample][kvdb][basic] ==================== kvdb_basic_sample ====================

[FlashDB][sample][kvdb][basic] get the 'boot_count' value is 96

[FlashDB][sample][kvdb][basic] set the 'boot_count' value to 97

[FlashDB][sample][kvdb][basic] ===========================================================

[FlashDB][sample][kvdb][basic] ==================== kvdb_basic_sample ====================

[FlashDB][sample][kvdb][basic] get the 'boot_count' value is 97

[FlashDB][kv][env][fdb_kvdb1] (..\..\..\src\fdb_kvdb.c:928) Trigger a GC check after alloc KV failed.

写到97后,触发GC回收。

#define FDB_GC_EMPTY_SEC_THRESHOLD                1

即保留了一个扇区不会写数据。

[FlashDB][kv][env][fdb_kvdb1] Warning: Alloc an KV (size 56) failed when new KV. Now will GC then retry.

[FlashDB][kv][env][fdb_kvdb1] (..\..\..\src\fdb_kvdb.c:1149) The remain empty sector is 1, GC threshold is 1.

LOG提示有一个空扇区。

GC先将扇区0的3条KV移到扇区3,然后删除扇区0。接着将要写的KV继续在扇区3内容后面写。

扇区3写满了,则删除1扇区。在第0扇区接着写数据。始终保持一个扇区空,用来GC。

第2轮时,出现一次写Flash错误。GC第0扇区(0x000000)没成功,再次GC了第1扇区。

后面就再也没有GC第0扇区。

再3轮后,GC第3扇区(0x00001800)时写出错。状态都为未使用了。

此时是在扇区2写数据,当写满后,就再也写不动了,写610写不进了。一直读出的是609.也没有报什么错误。

重开机再次测试到5000数,运行正常。可能是受干扰了。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值