因为最近在做一个关于对sqlite数据库的备份和恢复策略,对网上搜索了很多关于备份的策略,下面是对网上的资料进行整合,作出对数据库的备份和恢复策略的接口函数和示例,如有不对的地方请多指教,因为参考了官方文档,技术大牛的博客和源码,这里也忘记了具体的资料路径,本人绝对尊重所有原创作者,如有不妥,请多多包涵,这里只用于记录对数据库备份和恢复进行一个学习和探讨。
我们先来探讨一下sqlite3数据库完整性检测,下面是接口函数
#define DB_OK 0 /* 完整 */
#define DB_ERROR 1 /* 损坏 */
/*************************************************************************************************
* 函数名称: IntegrityCheck
* 功能描述: 数据库完整性检测
* 输入参数: g_objfile /数据库路径
* 输出参数: 无
* 返 回 值: 0:完整 / 1:损坏
* 其它说明:
**************************************************************************************************/
int IntegrityCheck(char *g_objfile)
{
sqlite3 *obj_db;
int ret = 0;
BOOL integrityVerified = DB_ERR;
sqlite3_stmt *integrity = NULL;
ret = sqlite3_open( g_objfile, &obj_db );
if(ret != SQLITE_OK)
{
SysLog("open db err!\n");
return -1;
}
// integrity_check检查包括:乱序的记录、缺页、错误的记录、丢失的索引、唯一性约束、非空约束
//if ( sqlite3_prepare_v2( obj_db, "PRAGMA integrity_check;", -1, &integrity, NULL ) == SQLITE_OK )
//quick_check不检查约束条件,耗时较短
if ( sqlite3_prepare_v2( obj_db, "PRAGMA integrity_check;", -1, &integrity, NULL ) == SQLITE_OK )
{
while ( sqlite3_step( integrity ) == SQLITE_ROW )
{
const unsigned char *result = sqlite3_column_text( integrity, 0 );
if ( result && strcmp( ( const char * )result, (const char *)"ok" ) == 0 )
{
integrityVerified = DB_OK;
break;
}
}
sqlite3_finalize( integrity );
}
/*关闭数据库*/
sqlite3_close( obj_db );
return integrityVerified;
}
数据库备份和恢复:使用sqlite3官方提供得库函数
1). 函数sqlite3_backup_init()用于创建sqlite3_backup对象,该对象将作为本次拷贝操作的句柄传给其余两个函数。
2). 函数sqlite3_backup_step()用于数据拷贝,如果该函数的第二个参数为-1,那么整个拷贝过程都将在该函数的一次调用中完成。
3). 函数sqlite3_backup_finish()用于释放sqlite3_backup_init()函数申请的资源,以避免资源泄露。
下面是备份和恢复的接口函数
/**********************************************************************
* 函数名称:loadOrSaveDb
* 功能描述:数据库备份与恢复(一次性拷贝完)
* 输入参数:pInMemory指向内存数据库指针
* zFilename: 指向文件数据库目录的字符串指针
* isSave 0: 从文件数据库载入到内存数据库
1:从内存数据库备份到文件数据库
* 输出参数:无
* 返 回 值: 状态码
* 其它说明:
***********************************************************************/
int loadOrSaveDb(sqlite3 *pInMemeory, const char *zFilename, int isSave)
{
int rc;
sqlite3 *pFile;
sqlite3_backup *pBackup;
sqlite3 *pTo;
sqlite3 *pFrom;
rc = sqlite3_open(zFilename, &pFile);
if(rc == SQLITE_OK)
{
pFrom = (isSave?pInMemeory:pFile);
pTo = (isSave?pFile:pInMemeory);
pBackup = sqlite3_backup_init(pTo,"main",pFrom,"main");
if(pBackup)
{
(void)sqlite3_backup_step(pBackup,-1);
(void)sqlite3_backup_finish(pBackup);
}
rc = sqlite3_errcode(pTo);
}
(void)sqlite3_close(pFile);
return rc;
}
数据库的恢复策略:首先检测数据库是否损坏,是则进行恢复
#define DB_PATH 数据库路径
#define DB_BACKUP_PATH 备份路径
void recoveryDB(void)
{
int ret = 0;
sqlite3 *memoryDb;
ret = sqlite3_open(DB_PATH, &memoryDb);
ret = IntegrityCheck(DB_PATH);
if(ret != 0)
{
loadOrSaveDb(memoryDb, DB_BACKUP_PATH,0); //进行数据库恢复,必须有备份好得数据库
}
}