SQLite入门与分析(7)

来源:网络收集 时间:2025-07-14 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:xuecool-com或QQ:370150219 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

}

pPager->origDbSize = pPager->dbSize; //写入日志文件的header---24个字节 rc = writeJournalHdr(pPager);

if( pPager->stmtAutoopen && rc==SQLITE_OK ){ rc = sqlite3pager_stmt_begin(pPager); }

if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){ rc = pager_unwritelock(pPager); if( rc==SQLITE_OK ){ rc = SQLITE_FULL; } }

return rc;

failed_to_open_journal:

sqliteFree(pPager->aInJournal); pPager->aInJournal = 0; if( rc==SQLITE_NOMEM ){

/* If this was a malloc() failure, then we will not be closing the pager ** file. So delete any journal file we may have just created. Otherwise, ** the system will get confused, we have a read-lock on the file and a ** mysterious journal has appeared in the filesystem. */

sqlite3OsDelete(pPager->zJournal); }else{

sqlite3OsUnlock(pPager->fd, NO_LOCK); pPager->state = PAGER_UNLOCK; }

return rc; }

/*写入日志文件头

**journal header的格式如下: ** - 8 bytes: 标志日志文件的魔数 ** - 4 bytes: 日志文件中记录数

** - 4 bytes: Random number used for page hash. ** - 4 bytes: 原来数据库的大小(kb) ** - 4 bytes: 扇区大小512byte */

static int writeJournalHdr(Pager *pPager){ //日志文件头

char zHeader[sizeof(aJournalMagic)+16];

int rc = seekJournalHdr(pPager); if( rc ) return rc;

pPager->journalHdr = pPager->journalOff; if( pPager->stmtHdrOff==0 ){

pPager->stmtHdrOff = pPager->journalHdr; }

//设置文件指针指向header之后

pPager->journalOff += JOURNAL_HDR_SZ(pPager);

/* FIX ME: **

** Possibly for a pager not in no-sync mode, the journal magic should not ** be written until nRec is filled in as part of next syncJournal(). **

** Actually maybe the whole journal header should be delayed until that ** point. Think about this. */

memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); /* The nRec Field. 0xFFFFFFFF for no-sync journals. */

put32bits(&zHeader[sizeof(aJournalMagic)], pPager->noSync ? 0xffffffff : 0); /* The random check-hash initialiser */

sqlite3Randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit); /* The initial database size */

put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbSize); /* The assumed sector size for this process */

put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize); //写入文件头

rc = sqlite3OsWrite(pPager->jfd, zHeader, sizeof(zHeader));

/* The journal header has been written successfully. Seek the journal ** file descriptor to the end of the journal header sector. */

if( rc==SQLITE_OK ){

rc = sqlite3OsSeek(pPager->jfd, pPager->journalOff-1); if( rc==SQLITE_OK ){

rc = sqlite3OsWrite(pPager->jfd, \ } }

return rc; }

其实现过程如下图所示:

主要参考:http://www.sqlite.org/atomiccommit.html

(四)Page Cache之事务处理(2)

写在前面:个人认为pager层是SQLite实现最为核心的模块,它具有四大功能:I/O,页面缓存,并发控制和日志恢复。而这些功能不仅是上层Btree的基础,而且对系统的性能和健壮性有关至关重要的影响。其中并发控制和日志恢复是事务处理实现的基础。SQLite并发控制的机制非常简单——封锁机制;别外,它的查询优化机制也非常简单——基于索引。这一切使得整个SQLite的实现变得简单,SQLite变得很小,运行速度也非常快,所以,特别适合嵌入式设备。好了,接下来讨论事务的剩余部分。

4.6、修改位于用户进程空间的页面(Changing Database Pages In User Space)

页面的原始数据写入日志之后,就可以修改页面了——位于用户进程空间。每个数据库连接都有自己私有的空间,所以页面的变化只对该连接可见,而对其它连接的数据仍然是磁盘缓存中的数据。从这里可以明白一件事:一个进程在修改页面数据的同时,其它进程可以继续进行读操作。图中的红色表示修改的页面。

4.7、日志文件刷入磁盘(Flushing The Rollback Journal File To Mass Storage)

接下来把日志文件的内容刷入磁盘,这对于数据库从意外中恢复来说是至关重要的一步。而且这通常也是一个耗时的操作,因为磁盘I/O速度很慢。 这个步骤不只把日志文件刷入磁盘那么简单,它的实现实际上分成两步:首先把日志文件的内容刷入磁盘(即页面数据);然后把日志文件中页面的数目写入日志文件头,再把header刷入磁盘(这一过程在代码中清晰可见)。

代码如下: /*

**Sync日志文件,保证所有的脏页面写入磁盘日志文件 */

static int syncJournal(Pager *pPager){ PgHdr *pPg;

int rc = SQLITE_OK;

/* Sync the journal before modifying the main database ** (assuming there is a journal and it needs to be synced.) */

if( pPager->needSync ){ if( !pPager->tempFile ){

assert( pPager->journalOpen );

/* assert( !pPager->noSync ); // noSync might be set if synchronous ** was turned off after the transaction was started. Ticket #615 */ #ifndef NDEBUG {

/* Make sure the pPager->nRec counter we are keeping agrees ** with the nRec computed from the size of the journal file. */ i64 jSz;

rc = sqlite3OsFileSize(pPager->jfd, &jSz); if( rc!=0 ) return rc;

assert( pPager->journalOff==jSz );

百度搜索“70edu”或“70教育网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,70教育网,提供经典综合文库SQLite入门与分析(7)在线全文阅读。

SQLite入门与分析(7).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.70edu.com/wenku/398168.html(转载请注明文章来源)
Copyright © 2020-2025 70教育网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:370150219 邮箱:370150219@qq.com
苏ICP备16052595号-17
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
单篇付费下载
限时特价:7 元/份 原价:20元
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:xuecool-com QQ:370150219