运行环境
正点原子STM32F429阿波罗开发板
CPU: 180M
SDRAM:32M
NAND:512M
NAND+UFFS挂载到根目录”/“
SD+FATFS挂载到”/sd”
兼容性问题修复
SQLite数据库RT-Thread的3.1.3以上及其以上的版本出现了些兼容性问题。
初始化报错
使用ENV配置并编译运行,在调用sqlite3_initialize时报错:(obj != object) assertion failed at function:rt_object_init, line number:267
根据报错定位至object.c文件rt_object_init方法中
/* try to find object */for (node = information->object_list.next;node != &(information->object_list);node = node->next){struct rt_object *obj;obj = rt_list_entry(node, struct rt_object, list);if (obj) /* skip warning when disable debug */{RT_ASSERT(obj != object);}}/* leave critical */
这段代码是为了放防止对象重复插入链表,意味着系统在初始化sqlite时有对象重复初始化了。通过单步调试以及查看已被压栈的方法及变量,发现是重复初始化导致,在头文件sqlite_config_rtthread.h中增加宏定义#define SQLITE_OMIT_AUTOINIT得以解决。
插入报错
初始化问题解决后,成功创建了数据库文件m.db。但是在执行插入操作是再次出现(obj != object) assertion failed at function:rt_object_init, line number:267
还是通过查看栈内方法及变量,配合单步调试定位到问题,在rtthread_io_methods.c和rtthread_vfs.c中,每次打开操作时都会调用rt_sem_init来初始化信号量”vfssem”作为文件描述符的锁,rt_sem_init会将信号量添加到对象列表,但是在关闭操作时未将”vfssem”从对象列表中剔除,导致了这个报错。所以在rtthread_io_methods.c文件_rtthread_io_close方法中增加rt_sem_detach操作:
static int _rtthread_io_close(sqlite3_file *file_id){int rc = 0;RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;if (file->fd >= 0){_rtthread_io_unlock(file_id, NO_LOCK);rt_sem_detach(&file->sem);rc = close(file->fd);file->fd = -1;}return rc;}
插入性能测试
创建表:CREATE TABLE userinfo(id INTEGER PRIMARY KEY AUTOINCREMENT,userid INT NOT NULL,username varchar(32) NOT NULL);
| id | userid | username |
|---|---|---|
| 1 | 1 | username1 |
| 2 | 2 | username2 |
普通插入
伪代码:
sqlite3_open(DB_NAME,&db);for(i=0;i<n;i++){sqlite3_exec(db,"insert into userinfo(userid,username) values (1001,\"username1001\");",0,0,NULL);}sqlite3_close(db);
UFFS:
Directory /:sd <DIR>udisk <DIR>m.db 12288msh />msh />user add[I/user_info] operat record(s): 226 msAdd 1 record(s): 232ms, speed: 232ms/recordmsh />user add 10[I/user_info] operat record(s): 2312 msAdd 10 record(s): 2318ms, speed: 231ms/record
显式开启事务
伪代码:
sqlite3_open(DB_NAME,&db);sqlite3_exec(db,"begin transaction;",0,0,0);for(i=0;i<n;i++){sqlite3_exec(db,"insert into userinfo(userid,username) values (1001,\"username1001\");",0,0,NULL);}sqlite3_exec(db,"commit transaction;",0,0,0);sqlite3_close(db);
UFFS:
msh />user add 10[I/user_info] operat record(s): 237 msAdd 10 record(s): 243ms, speed: 24ms/recordmsh />user add 1000[I/user_info] operat record(s): 1360 msAdd 1000 record(s): 1365ms, speed: 1ms/recordmsh />user add 10000[I/user_info] operat record(s): 12452 msAdd 10000 record(s): 12459ms, speed: 1ms/recordmsh />lsDirectory /:sd <DIR>udisk <DIR>m.db 270336msh />
SD+FATFS
Directory /sd:m.db 12288System Volume Information<DIR>msh /sd>user add[I/user_info] operat record(s): 245 msAdd 1 record(s): 256ms, speed: 256ms/recordmsh /sd>user add 10[I/user_info] operat record(s): 252 msAdd 10 record(s): 266ms, speed: 26ms/recordmsh /sd>user add 100[I/user_info] operat record(s): 341 msAdd 100 record(s): 355ms, speed: 3ms/recordmsh /sd>user add 1000[I/user_info] operat record(s): 1385 msAdd 1000 record(s): 1399ms, speed: 1ms/recordmsh /sd>user add 10000[I/user_info] operat record(s): 11314 msAdd 10000 record(s): 11329ms, speed: 1ms/recordmsh /sd>
显式开启事务+执行准备
伪代码:
sqlite3_open(DB_NAME, &db);sqlite3_exec(db, "begin transaction;", 0, 0, 0);sqlite3_prepare(db, sql, -1, &stmt, NULL);for(i = 0; i < n; i++){sqlite3_bind_int(stmt, 1, e->userid);sqlite3_bind_text(stmt, 2, e->username, strlen(e->username), NULL);rc = sqlite3_step(stmt);}sqlite3_finalize(stmt);sqlite3_exec(db, "commit transaction;", 0, 0, 0);sqlite3_close(db);
UFFS:
msh />lsDirectory /:sd <DIR>udisk <DIR>m.db 12288msh />user add 1000[I/dbhelper] insert record(s): 668 msAdd 1000 record(s): 674ms, speed: 0.7ms/recordmsh />usertest get all userinfoid:101 userid:3425 username:UserName3425id:102 userid:3425 username:UserName3425id:103 userid:3425 username:UserName3425...id:1098 userid:3425 username:UserName3425id:1099 userid:3425 username:UserName3425id:1100 userid:3425 username:UserName3425record(s):1000msh />lsDirectory /:sd <DIR>udisk <DIR>m.db 36864msh />user add[I/dbhelper] operat record(s): 227 msAdd 1 record(s): 234ms, speed: 234ms/recordmsh />user add 10000[I/dbhelper] operat record(s): 6666 msAdd 10000 record(s): 6673ms, speed: 0.7ms/recordmsh />msh />user del[I/dbhelper] operat record(s): 1174 msDel all record success!msh />
SD+FATFS
msh /sd>user add
[I/dbhelper] operat record(s): 244 ms
Add 1 record(s): 256ms, speed: 256ms/record
msh /sd>user add 100
[I/dbhelper] operat record(s): 283 ms
Add 100 record(s): 296ms, speed: 2.8ms/record
msh /sd>user add 1000
[I/dbhelper] operat record(s): 776 ms
Add 1000 record(s): 789ms, speed: 0.7ms/record
msh /sd>user add 10000
[I/dbhelper] operat record(s): 5415 ms
Add 10000 record(s): 5431ms, speed: 0.5ms/record
msh /sd>
开启事务
| 存储 | 1条(ms) | 100条(ms) | 1000条(ms) | 10000条(ms) |
|---|---|---|---|---|
| uffs | 227 | 323 | 1378 | 12452 |
| sd+fatfs | 245 | 341 | 1385 | 11314 |
开启事务+执行准备
| 存储 | 1条(ms) | 100条(ms) | 1000条(ms) | 10000条(ms) |
|---|---|---|---|---|
| uffs | 227 | 265 | 669 | 6670 |
| sd+fatfs | 244 | 283 | 776 | 5415 |
当单表数据量达到6W至30W条数据时,单条插入或100条批量插入时间会达到700ms以上,1000条批量插入时间1500-2000ms。根据id单条查询时间未收影响。
