77范文网 - 专业文章范例文档资料分享平台

SQLite入门与分析(8)

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

} #endif {

/* Write the nRec value into the journal file header. If in

** full-synchronous mode, sync the journal first. This ensures that ** all data has really hit the disk before nRec is updated to mark ** it as a candidate for rollback. */

if( pPager->fullSync ){

TRACE2(\

//首先保证脏页面中所有的数据都已经写入日志文件 rc = sqlite3OsSync(pPager->jfd, 0); if( rc!=0 ) return rc; }

rc = sqlite3OsSeek(pPager->jfd,

pPager->journalHdr + sizeof(aJournalMagic)); if( rc ) return rc;

//页面的数目写入日志文件

rc = write32bits(pPager->jfd, pPager->nRec); if( rc ) return rc;

rc = sqlite3OsSeek(pPager->jfd, pPager->journalOff); if( rc ) return rc; }

TRACE2(\ rc = sqlite3OsSync(pPager->jfd, pPager->full_fsync); if( rc!=0 ) return rc;

pPager->journalStarted = 1; }

pPager->needSync = 0;

/* Erase the needSync flag from every page. */

//清除needSync标志位

for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ pPg->needSync = 0; }

pPager->pFirstSynced = pPager->pFirst; }

#ifndef NDEBUG

/* If the Pager.needSync flag is clear then the PgHdr.needSync ** flag must also be clear for all pages. Verify that this ** invariant is true.

*/ else{

for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ assert( pPg->needSync==0 ); }

assert( pPager->pFirstSynced==pPager->pFirst ); } #endif

return rc; }

4.8、获取排斥锁(Obtaining An Exclusive Lock)

在对数据库文件进行修改之前(注:这里不是内存中的页面),我们必须得到数据库文件的排斥锁(Exclusive Lock)。得到排斥锁的过程可分为两步:首先得到Pending lock;然后Pending lock升级到exclusive lock。

Pending lock允许其它已经存在的Shared lock继续读数据库文件,但是不允许产生新的shared lock,这样做目的是为了防止写操作发生饿死情况。一旦所有的shared lock完成操作,则pending lock升级到exclusive lock。

4.9、修改的页面写入文件(Writing Changes To The Database File)

一旦得到exclusive lock,其它的进程就不能进行读操作,此时就可以把修改的页面写回数据库文件,但是通常OS都把结果暂时保存到磁盘缓存中,直到某个时刻才会真正把结果写入磁盘。

以上两步的实现代码:

//把所有的脏页面写入数据库

//到这里开始获取EXCLUSIVEQ锁,并将页面写回操作系统文件 static int pager_write_pagelist(PgHdr *pList){ Pager *pPager; int rc;

if( pList==0 ) return SQLITE_OK; pPager = pList->pPager;

/* At this point there may be either a RESERVED or EXCLUSIVE lock on the ** database file. If there is already an EXCLUSIVE lock, the following ** calls to sqlite3OsLock() are no-ops. **

** Moving the lock from RESERVED to EXCLUSIVE actually involves going

** through an intermediate state PENDING. A PENDING lock prevents new ** readers from attaching to the database but is unsufficient for us to ** write. The idea of a PENDING lock is to prevent new readers from

** coming in while we wait for existing readers to clear. **

** While the pager is in the RESERVED state, the original database file ** is unchanged and we can rollback without having to playback the ** journal into the original database file. Once we transition to

** EXCLUSIVE, it means the database file has been changed and any rollback ** will require a journal playback. */

//加EXCLUSIVE_LOCK锁

rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); if( rc!=SQLITE_OK ){ return rc; }

while( pList ){

assert( pList->dirty );

rc = sqlite3OsSeek(pPager->fd, (pList->pgno-1)*(i64)pPager->pageSize); if( rc ) return rc;

/* If there are dirty pages in the page cache with page numbers greater ** than Pager.dbSize, this means sqlite3pager_truncate() was called to ** make the file smaller (presumably by auto-vacuum code). Do not write ** any such pages to the file. */

if( pList->pgno<=pPager->dbSize ){

char *pData = CODEC2(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6); TRACE3(\ //写入文件

rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize); TEST_INCR(pPager->nWrite); }

#ifndef NDEBUG else{

TRACE3(\ } #endif

if( rc ) return rc; //设置dirty pList->dirty = 0;

#ifdef SQLITE_CHECK_PAGES

pList->pageHash = pager_pagehash(pList); #endif

//指向下一个脏页面 pList = pList->pDirty; }

return SQLITE_OK; }

4.10、修改结果刷入存储设备(Flushing Changes To Mass Storage)

为了保证修改结果真正写入磁盘,这一步必不要少。对于数据库存的完整性,这一步也是关键的一步。由于要进行实际的I/O操作,所以和第7步一样,将花费较多的时间。

最后来看看这几步是如何实现的:

其实以上以上几步是在函数sqlite3BtreeSync()---btree.c中调用的(而关于该函数的调用后面再讲)。

代码如下: Code

//同步btree对应的数据库文件

//该函数返回之后,只需要提交写事务,删除日志文件 int sqlite3BtreeSync(Btree *p, const char *zMaster){ int rc = SQLITE_OK;

if( p->inTrans==TRANS_WRITE ){ BtShared *pBt = p->pBt;

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

SQLite入门与分析(8).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/zonghe/398168.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: