运行环境
正点原子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 12288
msh />
msh />user add
[I/user_info] operat record(s): 226 ms
Add 1 record(s): 232ms, speed: 232ms/record
msh />user add 10
[I/user_info] operat record(s): 2312 ms
Add 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 ms
Add 10 record(s): 243ms, speed: 24ms/record
msh />user add 1000
[I/user_info] operat record(s): 1360 ms
Add 1000 record(s): 1365ms, speed: 1ms/record
msh />user add 10000
[I/user_info] operat record(s): 12452 ms
Add 10000 record(s): 12459ms, speed: 1ms/record
msh />ls
Directory /:
sd <DIR>
udisk <DIR>
m.db 270336
msh />
SD+FATFS
Directory /sd:
m.db 12288
System Volume Information<DIR>
msh /sd>user add
[I/user_info] operat record(s): 245 ms
Add 1 record(s): 256ms, speed: 256ms/record
msh /sd>user add 10
[I/user_info] operat record(s): 252 ms
Add 10 record(s): 266ms, speed: 26ms/record
msh /sd>user add 100
[I/user_info] operat record(s): 341 ms
Add 100 record(s): 355ms, speed: 3ms/record
msh /sd>user add 1000
[I/user_info] operat record(s): 1385 ms
Add 1000 record(s): 1399ms, speed: 1ms/record
msh /sd>user add 10000
[I/user_info] operat record(s): 11314 ms
Add 10000 record(s): 11329ms, speed: 1ms/record
msh /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 />ls
Directory /:
sd <DIR>
udisk <DIR>
m.db 12288
msh />user add 1000
[I/dbhelper] insert record(s): 668 ms
Add 1000 record(s): 674ms, speed: 0.7ms/record
msh />user
test get all userinfo
id:101 userid:3425 username:UserName3425
id:102 userid:3425 username:UserName3425
id:103 userid:3425 username:UserName3425
...
id:1098 userid:3425 username:UserName3425
id:1099 userid:3425 username:UserName3425
id:1100 userid:3425 username:UserName3425
record(s):1000
msh />ls
Directory /:
sd <DIR>
udisk <DIR>
m.db 36864
msh />user add
[I/dbhelper] operat record(s): 227 ms
Add 1 record(s): 234ms, speed: 234ms/record
msh />user add 10000
[I/dbhelper] operat record(s): 6666 ms
Add 10000 record(s): 6673ms, speed: 0.7ms/record
msh />
msh />user del
[I/dbhelper] operat record(s): 1174 ms
Del 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单条查询时间未收影响。