sqlite db上的C程序无法打开数据库文件
首先,我必须说,这不是一个重复的线程,因为我的另一个类似线程与这个主题有关。 我为一些测试编写了这个简单的sqlite C程序,但它不会关闭sqlite db,在MySqlite_close函数中没有错误,但过了一段时间,当它达到最大打开文件数时,它打印出无法打开数据库文件:sqlite db上的C程序无法打开数据库文件,c,database,sqlite,C,Database,Sqlite,首先,我必须说,这不是一个重复的线程,因为我的另一个类似线程与这个主题有关。 我为一些测试编写了这个简单的sqlite C程序,但它不会关闭sqlite db,在MySqlite_close函数中没有错误,但过了一段时间,当它达到最大打开文件数时,它打印出无法打开数据库文件: #include <stdio.h> #include <stdlib.h> #include <sqlite3.h> #include <string.h> #in
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <string.h>
#include <time.h>
#define SQLITE_MAIN_BASE "/var/"
#define SQLITE_DEVLOG_BASE "./"
#define Create_All_Database_Error 1
MySqlite_close(sqlite3 *db)
{
int i=0,
rc=0;
rc=sqlite3_close(db);
while(rc != SQLITE_OK)
{
printf("yet closing\n");
if (rc == SQLITE_BUSY)
{
printf("it is busy\n");
i++;
if ( i > 10 )
{
return rc;
}
}
sleep(1);
rc=sqlite3_close(db);
}
printf("2closeeeeeee\n\n");
return 0;
}
int MySqlite_Exec(const char *dbname,sqlite3 *db,const char *query,sqlite3_stmt **retStmt,const char *queryTail2,const char *logpath,int logfd,int mode)
{
char logmessage[1500];
char dbfilepath[150];
int rc=0;
sprintf(dbfilepath,"%s%s",SQLITE_DEVLOG_BASE,dbname);
fprintf(stdout,"%s\n",query);
while(sqlite3_open(dbfilepath, &db))
{
sprintf(logmessage,"1Error on \"%s\" : %u %s ",query,sqlite3_errcode(db), sqlite3_errmsg(db));
printf("%s\n",logmessage);
sleep(10);
MySqlite_close(db);
return 0;
}
printf("10\n");
if( sqlite3_prepare_v2(db, query, -1, retStmt,NULL) != SQLITE_OK )
{
sprintf(logmessage,"2Error on \"%s\" : %u %s ",query,sqlite3_errcode(db), sqlite3_errmsg(db));
printf("%s\n",logmessage);
while(sqlite3_prepare_v2(db, query, -1, retStmt,NULL) == SQLITE_BUSY)
{
sprintf(logmessage,"2Error on \"%s\" : %u %s ",query,sqlite3_errcode(db), sqlite3_errmsg(db));
printf("%s\n",logmessage);
sleep(1);
}
}
printf("12\n");
if (mode==0)
{
printf("222\n");
if (sqlite3_step(*retStmt) != SQLITE_DONE)
{
sprintf(logmessage,"3Error on \"%s\" : %u %s ",query,sqlite3_errcode(db), sqlite3_errmsg(db));
printf("%s\n",logmessage);
}
if (sqlite3_reset(*retStmt) != SQLITE_OK)
{
sprintf(logmessage,"5Error on \"%s\" : %u %s ",query,sqlite3_errcode(db), sqlite3_errmsg(db));
printf("%s\n",logmessage);
}
if ( *retStmt != NULL )
{
printf("retStmt is not NULL\n");
while(sqlite3_finalize(*retStmt)!=SQLITE_OK)
{
sprintf(logmessage,"20Error on : %u %s ",sqlite3_errcode(db), sqlite3_errmsg(db));
printf("%s\n",logmessage);
printf("finilized NOT ok\n");
sleep(1);
}
printf("finilized ok\n");
*retStmt=NULL;
}
else
{
printf("retStmt is NULL\n");
}
MySqlite_close(db);
}
return 0;
}
int Create_SqltDB(void)
{
char hostip[20],
LOG_FILE[100],
query[1000],
dbfilepath[100],
logmessage[1500];
int result=0;
const char *queryTail;
sqlite3 *db;
sqlite3_stmt *retStmt=NULL;
sprintf(LOG_FILE,"/var/log/Emain.log");
sprintf(query,"create table if not exists lastuptime(row integer primary key not NULL,microupdatetime double default 0 not NULL,time double default 0 not NULL);");
if (MySqlite_Exec("lastuptime",db,query,&retStmt,queryTail,LOG_FILE,2,0))
{
return Create_All_Database_Error;
}
return 0;
}
int main()
{
sqlite3 *db;
Create_SqltDB();
char query[1000],
logmessage[1500],
LOG_FILE[100];
int i=0,
result=0;
sqlite3_stmt *retStmt=NULL;
const char *queryTail;
/*
for (i=0; i<1100;i++)
{
sprintf(query,"insert into lastuptime(microupdatetime,time) values (%i,%i);",i,i);
if (MySqlite_Exec("lastuptime",db,query,&retStmt,queryTail,LOG_FILE,2,0))
{
return Create_All_Database_Error;
}
}
*/
while(1)
{
sprintf(query,"select * from lastuptime where row%%1000=0;");
if (MySqlite_Exec("lastuptime",db,query,&retStmt,queryTail,LOG_FILE,2,1))
{
return Create_All_Database_Error;
}
do
{
result = sqlite3_step (retStmt) ;
if (result == SQLITE_ROW) /* can read data */
{
printf(" %d \t|\t %f \t|\t '%f' \n",\
sqlite3_column_int(retStmt,0),\
sqlite3_column_double(retStmt,1),\
sqlite3_column_double(retStmt,2)) ;
}
else
{
printf("no data\n");
}
} while (result == SQLITE_ROW) ;
printf("s1\n");
MySqlite_close(db);
printf("s2\n");
}
return 0;
}
您忘记调用sqlite3\u finalize,因此数据库永远不会关闭
请注意,这是最新的SQLite版本;您的行为可能会有所不同。我终于找到了指针问题的解决方案。我的整个更改代码如下所示:注意Mysqlite_exec函数中的db指针的更改以及其他函数中的其他调用,我没有完成我的声明:
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <string.h>
#include <time.h>
#include "regex.c"
#define SQLITE_MAIN_BASE "/var/"
#define SQLITE_DEVLOG_BASE "./"
#define Create_All_Database_Error 1
MySqlite_close(sqlite3 *db)
{
int i=0,
rc=0;
rc=sqlite3_close(db);
while(rc != SQLITE_OK)
{
printf("yet closing\n");
if (rc == SQLITE_BUSY)
{
printf("it is busy\n");
i++;
if ( i > 10 )
{
return rc;
}
}
sleep(1);
rc=sqlite3_close(db);
}
printf("2closeeeeeee\n\n");
return 0;
}
int Mysqlite_finalize(sqlite3 *db,sqlite3_stmt **retStmt)
{
char logmessage[1500];
/* if (sqlite3_reset(*retStmt) != SQLITE_OK)
{
sprintf(logmessage,"5Error is : %u %s ",sqlite3_errcode(db), sqlite3_errmsg(db));
printf("%s\n",logmessage);
}
*/
if ( *retStmt != NULL )
{
printf("retStmt is not NULL\n");
while(sqlite3_finalize(*retStmt)!=SQLITE_OK)
{
sprintf(logmessage,"20Error on : %u %s ",sqlite3_errcode(db), sqlite3_errmsg(db));
printf("%s\n",logmessage);
printf("finilized NOT ok\n");
sleep(1);
}
printf("finilized ok\n");
*retStmt=NULL;
}
else
{
printf("retStmt is NULL\n");
}
return 0;
}
int MySqlite_Exec(const char *dbname,sqlite3 **db,const char *query,sqlite3_stmt **retStmt,const char *queryTail2,const char *logpath,int logfd)
{
char logmessage[1500];
char dbfilepath[150];
int rc=0;
sprintf(dbfilepath,"%s%s",SQLITE_DEVLOG_BASE,dbname);
fprintf(stdout,"%s\n",query);
while(sqlite3_open(dbfilepath, db))
{
sprintf(logmessage,"1Error on \"%s\" : %u %s ",query,sqlite3_errcode(*db), sqlite3_errmsg(*db));
printf("%s\n",logmessage);
sleep(10);
MySqlite_close(*db);
return 0;
}
printf("10\n");
if( sqlite3_prepare_v2(*db, query, -1, retStmt,NULL) != SQLITE_OK )
{
sprintf(logmessage,"2Error on \"%s\" : %u %s ",query,sqlite3_errcode(*db), sqlite3_errmsg(*db));
printf("%s\n",logmessage);
while(sqlite3_prepare_v2(*db, query, -1, retStmt,NULL) == SQLITE_BUSY)
{
sprintf(logmessage,"2Error on \"%s\" : %u %s ",query,sqlite3_errcode(*db), sqlite3_errmsg(*db));
printf("%s\n",logmessage);
sleep(1);
}
}
printf("12\n");
if ( MyRegexMatch(query,"^select",REG_ICASE) !=0 )
{
printf("222\n");
if (sqlite3_step(*retStmt) != SQLITE_DONE)
{
sprintf(logmessage,"3Error on \"%s\" : %u %s ",query,sqlite3_errcode(*db), sqlite3_errmsg(*db));
printf("%s\n",logmessage);
}
Mysqlite_finalize(*db,retStmt);
MySqlite_close(*db);
}
return 0;
}
int Create_SqltDB(void)
{
char hostip[20],
LOG_FILE[100],
query[1000],
dbfilepath[100],
logmessage[1500];
int result=0;
const char *queryTail;
sqlite3 *db;
sqlite3_stmt *retStmt=NULL;
sprintf(LOG_FILE,"/var/log/Emain.log");
sprintf(query,"create table if not exists lastuptime(row integer primary key not NULL,microupdatetime double default 0 not NULL,time double default 0 not NULL);");
if (MySqlite_Exec("lastuptime",&db,query,&retStmt,queryTail,LOG_FILE,2))
{
return Create_All_Database_Error;
}
return 0;
}
int main()
{
sqlite3 *db;
Create_SqltDB();
char query[1000],
logmessage[1500],
LOG_FILE[100];
int i=0,
result=0;
sqlite3_stmt *retStmt=NULL;
const char *queryTail;
for (i=0; i<100;i++)
{
sprintf(query,"insert into lastuptime(microupdatetime,time) values (%i,%i);",i,i);
if (MySqlite_Exec("lastuptime",&db,query,&retStmt,queryTail,LOG_FILE,2))
{
return Create_All_Database_Error;
}
}
while(1)
{
sprintf(query,"select * from lastuptime where row%%100=0;");
if (MySqlite_Exec("lastuptime",&db,query,&retStmt,queryTail,LOG_FILE,2))
{
return Create_All_Database_Error;
}
while(sqlite3_step(retStmt) == SQLITE_ROW) /* can read data */
{
printf(" %d \t|\t %f \t|\t '%f' \n",\
sqlite3_column_int(retStmt,0),\
sqlite3_column_double(retStmt,1),\
sqlite3_column_double(retStmt,2)) ;
}
printf("s1\n");
Mysqlite_finalize(db,&retStmt);
MySqlite_close(db);
printf("s2\n");
}
return 0;
}
您确定这是由于达到了文件描述符的最大数量而导致的吗?你是怎么推断的?是的,我确定,因为没有其他进程锁定,而且它总是在固定数量的打开db文件之后发生,我用:lsof-p pidof MYPROCESSNAME看到了这一点
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <string.h>
#include <time.h>
#include "regex.c"
#define SQLITE_MAIN_BASE "/var/"
#define SQLITE_DEVLOG_BASE "./"
#define Create_All_Database_Error 1
MySqlite_close(sqlite3 *db)
{
int i=0,
rc=0;
rc=sqlite3_close(db);
while(rc != SQLITE_OK)
{
printf("yet closing\n");
if (rc == SQLITE_BUSY)
{
printf("it is busy\n");
i++;
if ( i > 10 )
{
return rc;
}
}
sleep(1);
rc=sqlite3_close(db);
}
printf("2closeeeeeee\n\n");
return 0;
}
int Mysqlite_finalize(sqlite3 *db,sqlite3_stmt **retStmt)
{
char logmessage[1500];
/* if (sqlite3_reset(*retStmt) != SQLITE_OK)
{
sprintf(logmessage,"5Error is : %u %s ",sqlite3_errcode(db), sqlite3_errmsg(db));
printf("%s\n",logmessage);
}
*/
if ( *retStmt != NULL )
{
printf("retStmt is not NULL\n");
while(sqlite3_finalize(*retStmt)!=SQLITE_OK)
{
sprintf(logmessage,"20Error on : %u %s ",sqlite3_errcode(db), sqlite3_errmsg(db));
printf("%s\n",logmessage);
printf("finilized NOT ok\n");
sleep(1);
}
printf("finilized ok\n");
*retStmt=NULL;
}
else
{
printf("retStmt is NULL\n");
}
return 0;
}
int MySqlite_Exec(const char *dbname,sqlite3 **db,const char *query,sqlite3_stmt **retStmt,const char *queryTail2,const char *logpath,int logfd)
{
char logmessage[1500];
char dbfilepath[150];
int rc=0;
sprintf(dbfilepath,"%s%s",SQLITE_DEVLOG_BASE,dbname);
fprintf(stdout,"%s\n",query);
while(sqlite3_open(dbfilepath, db))
{
sprintf(logmessage,"1Error on \"%s\" : %u %s ",query,sqlite3_errcode(*db), sqlite3_errmsg(*db));
printf("%s\n",logmessage);
sleep(10);
MySqlite_close(*db);
return 0;
}
printf("10\n");
if( sqlite3_prepare_v2(*db, query, -1, retStmt,NULL) != SQLITE_OK )
{
sprintf(logmessage,"2Error on \"%s\" : %u %s ",query,sqlite3_errcode(*db), sqlite3_errmsg(*db));
printf("%s\n",logmessage);
while(sqlite3_prepare_v2(*db, query, -1, retStmt,NULL) == SQLITE_BUSY)
{
sprintf(logmessage,"2Error on \"%s\" : %u %s ",query,sqlite3_errcode(*db), sqlite3_errmsg(*db));
printf("%s\n",logmessage);
sleep(1);
}
}
printf("12\n");
if ( MyRegexMatch(query,"^select",REG_ICASE) !=0 )
{
printf("222\n");
if (sqlite3_step(*retStmt) != SQLITE_DONE)
{
sprintf(logmessage,"3Error on \"%s\" : %u %s ",query,sqlite3_errcode(*db), sqlite3_errmsg(*db));
printf("%s\n",logmessage);
}
Mysqlite_finalize(*db,retStmt);
MySqlite_close(*db);
}
return 0;
}
int Create_SqltDB(void)
{
char hostip[20],
LOG_FILE[100],
query[1000],
dbfilepath[100],
logmessage[1500];
int result=0;
const char *queryTail;
sqlite3 *db;
sqlite3_stmt *retStmt=NULL;
sprintf(LOG_FILE,"/var/log/Emain.log");
sprintf(query,"create table if not exists lastuptime(row integer primary key not NULL,microupdatetime double default 0 not NULL,time double default 0 not NULL);");
if (MySqlite_Exec("lastuptime",&db,query,&retStmt,queryTail,LOG_FILE,2))
{
return Create_All_Database_Error;
}
return 0;
}
int main()
{
sqlite3 *db;
Create_SqltDB();
char query[1000],
logmessage[1500],
LOG_FILE[100];
int i=0,
result=0;
sqlite3_stmt *retStmt=NULL;
const char *queryTail;
for (i=0; i<100;i++)
{
sprintf(query,"insert into lastuptime(microupdatetime,time) values (%i,%i);",i,i);
if (MySqlite_Exec("lastuptime",&db,query,&retStmt,queryTail,LOG_FILE,2))
{
return Create_All_Database_Error;
}
}
while(1)
{
sprintf(query,"select * from lastuptime where row%%100=0;");
if (MySqlite_Exec("lastuptime",&db,query,&retStmt,queryTail,LOG_FILE,2))
{
return Create_All_Database_Error;
}
while(sqlite3_step(retStmt) == SQLITE_ROW) /* can read data */
{
printf(" %d \t|\t %f \t|\t '%f' \n",\
sqlite3_column_int(retStmt,0),\
sqlite3_column_double(retStmt,1),\
sqlite3_column_double(retStmt,2)) ;
}
printf("s1\n");
Mysqlite_finalize(db,&retStmt);
MySqlite_close(db);
printf("s2\n");
}
return 0;
}