日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQLite学习手册(在线备份)

發布時間:2025/3/12 数据库 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQLite学习手册(在线备份) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、常用備份:

?? ?下面的方法是比較簡單且常用的SQLite數據庫備份方式,見如下步驟:
?? ?1). 使用SQLite API或Shell工具在源數據庫文件上加共享鎖。
?? ?2). 使用Shell工具(cp或copy)拷貝數據庫文件到備份目錄。
?? ?3). 解除數據庫文件上的共享鎖。
?? ?以上3個步驟可以應用于大多數場景,而且速度也比較快,然而卻存在一定的剛性缺陷,如:
?? ?1). 所有打算在源數據庫上執行寫操作的連接都不得不被掛起,直到整個拷貝過程結束并釋放文件共享鎖。
?? ?2). 不能拷貝數據到in-memory數據庫。
?? ?3). 在拷貝過程中,一旦備份數據庫所在的主機出現任何突發故障,備份數據庫可能會被破壞。
??? 在SQLite中提供了一組用于在線數據庫備份的APIs函數(C接口),可以很好的解決上述方法存在的不足。通過該組函數,可以將源數據庫中的內容拷貝到另一個數據庫,同時覆蓋目標數據庫中的數據。整個拷貝過程可以以增量的方式完成,在此情況下,源數據庫也不需要在整個拷貝過程中都被加鎖,而只是在真正讀取數據時加共享鎖。這樣,其它的用戶在訪問源數據庫時就不會被掛起。
???
二、在線備份APIs簡介:

?? ?SQLite提供了以下3個APIs函數用于完成此操作,這里僅僅給出它們的基本用法,至于使用細節可以參考SQLite官方網站"APIs Reference"(http://www.sqlite.org/c3ref/backup_finish.html)。
??? 1). 函數sqlite3_backup_init()用于創建sqlite3_backup對象,該對象將作為本次拷貝操作的句柄傳給其余兩個函數。
?? ?2). 函數sqlite3_backup_step()用于數據拷貝,如果該函數的第二個參數為-1,那么整個拷貝過程都將在該函數的一次調用中完成。
?? ?3). 函數sqlite3_backup_finish()用于釋放sqlite3_backup_init()函數申請的資源,以避免資源泄露。
?? ?在整個拷貝過程中如果出現任何錯誤,我們都可以通過調用目的數據庫連接的sqlite3_errcode()函數來獲取具體的錯誤碼。此外,如果sqlite3_backup_step()調用失敗,由于sqlite3_backup_finish()函數并不會修改當前連接的錯誤碼,因此我們可以在調用sqlite3_backup_finish()之后再獲取錯誤碼,從而在代碼中減少了一次錯誤處理。見如下代碼示例(來自SQLite官網):

1 /* 2 ** This function is used to load the contents of a database file on disk 3 ** into the "main" database of open database connection pInMemory, or 4 ** to save the current contents of the database opened by pInMemory into 5 ** a database file on disk. pInMemory is probably an in-memory database, 6 ** but this function will also work fine if it is not. 7 ** 8 ** Parameter zFilename points to a nul-terminated string containing the 9 ** name of the database file on disk to load from or save to. If parameter 10 ** isSave is non-zero, then the contents of the file zFilename are 11 ** overwritten with the contents of the database opened by pInMemory. If 12 ** parameter isSave is zero, then the contents of the database opened by 13 ** pInMemory are replaced by data loaded from the file zFilename. 14 ** 15 ** If the operation is successful, SQLITE_OK is returned. Otherwise, if 16 ** an error occurs, an SQLite error code is returned. 17 */ 18 int loadOrSaveDb(sqlite3 *pInMemory, const char *zFilename, int isSave){ 19 int rc; /* Function return code */ 20 sqlite3 *pFile; /* Database connection opened on zFilename */ 21 sqlite3_backup *pBackup; /* Backup object used to copy data */ 22 sqlite3 *pTo; /* Database to copy to (pFile or pInMemory) */ 23 sqlite3 *pFrom; /* Database to copy from (pFile or pInMemory) */ 24 25 /* Open the database file identified by zFilename. Exit early if this fails 26 ** for any reason. */ 27 rc = sqlite3_open(zFilename, &pFile); 28 if( rc==SQLITE_OK ){ 29 30 /* If this is a 'load' operation (isSave==0), then data is copied 31 ** from the database file just opened to database pInMemory. 32 ** Otherwise, if this is a 'save' operation (isSave==1), then data 33 ** is copied from pInMemory to pFile. Set the variables pFrom and 34 ** pTo accordingly. */ 35 pFrom = (isSave ? pInMemory : pFile); 36 pTo = (isSave ? pFile : pInMemory); 37 38 /* Set up the backup procedure to copy from the "main" database of 39 ** connection pFile to the main database of connection pInMemory. 40 ** If something goes wrong, pBackup will be set to NULL and an error 41 ** code and message left in connection pTo. 42 ** 43 ** If the backup object is successfully created, call backup_step() 44 ** to copy data from pFile to pInMemory. Then call backup_finish() 45 ** to release resources associated with the pBackup object. If an 46 ** error occurred, then an error code and message will be left in 47 ** connection pTo. If no error occurred, then the error code belonging 48 ** to pTo is set to SQLITE_OK. 49 */ 50 pBackup = sqlite3_backup_init(pTo, "main", pFrom, "main"); 51 if( pBackup ){ 52 (void)sqlite3_backup_step(pBackup, -1); 53 (void)sqlite3_backup_finish(pBackup); 54 } 55 rc = sqlite3_errcode(pTo); 56 } 57 58 /* Close the database connection opened on database file zFilename 59 ** and return the result of this function. */ 60 (void)sqlite3_close(pFile); 61 return rc; 62 }

???
三、高級應用技巧:
?? ?
?? ?在上面的例子中,我們是通過sqlite3_backup_step()函數的一次調用完成了整個拷貝過程。該實現方式仍然存在之前說過的掛起其它寫訪問連接的問題,為了解決該問題,這里我們將繼續介紹另外一種更高級的實現方式--分片拷貝,其實現步驟如下:
?? ?1). 函數sqlite3_backup_init()用于創建sqlite3_backup對象,該對象將作為本次拷貝操作的句柄傳給其余兩個函數。
?? ?2). 函數sqlite3_backup_step()被調用用于拷貝數據,和之前方法不同的是,該函數的第二個參數不再是-1,而是一個普通的正整數,表示每次調用將會拷貝的頁面數量,如5。
?? ?3). 如果在函數sqlite3_backup_step()調用結束后,仍然有更多的頁面需要被拷貝,那么我們將主動休眠250ms,然后再重復步驟2).
?? ?4). 函數sqlite3_backup_finish()用于釋放sqlite3_backup_init()函數申請的資源,以避免資源泄露。
??? 在上述步驟3)中我們主動休眠250ms,此期間,該拷貝操作不會在源數據庫上持有任何讀鎖,這樣其它的數據庫連接在進行寫操作時亦將不會被掛起。然而在休眠期間,如果另外一個線程或進程對源數據庫進行了寫操作,SQLite將會檢測到該事件的發生,從而在下一次調用sqlite3_backup_step()函數時重新開始整個拷貝過程。唯一的例外是,如果源數據庫不是in-memory數據庫,同時寫操作是在與拷貝操作同一個進程內完成,并且在操作時使用的也是同一個數據庫連接句柄,那么目的數據庫中數據也將被此操作同時自動修改。在下一次調用sqlite3_backup_step()時,也將不會有任何影響發生。  
??? 事實上,在SQLite中仍然提供了另外兩個輔助性函數backup_remaining()backup_pagecount(),其中前者將返回在當前備份操作中還有多少頁面需要被拷貝,而后者將返回本次操作總共需要拷貝的頁面數量。顯而易見的是,通過這兩個函數的返回結果,我們可以實時顯示本次備份操作的整體進度,計算公式如下:
?? ?Completion = 100% * (pagecount() - remaining()) / pagecount()
??? 見以下代碼示例(來自SQLite官網):

1 /* 2 ** Perform an online backup of database pDb to the database file named 3 ** by zFilename. This function copies 5 database pages from pDb to 4 ** zFilename, then unlocks pDb and sleeps for 250 ms, then repeats the 5 ** process until the entire database is backed up. 6 ** 7 ** The third argument passed to this function must be a pointer to a progress 8 ** function. After each set of 5 pages is backed up, the progress function 9 ** is invoked with two integer parameters: the number of pages left to 10 ** copy, and the total number of pages in the source file. This information 11 ** may be used, for example, to update a GUI progress bar. 12 ** 13 ** While this function is running, another thread may use the database pDb, or 14 ** another process may access the underlying database file via a separate 15 ** connection. 16 ** 17 ** If the backup process is successfully completed, SQLITE_OK is returned. 18 ** Otherwise, if an error occurs, an SQLite error code is returned. 19 */ 20 int backupDb( 21 sqlite3 *pDb, /* Database to back up */ 22 const char *zFilename, /* Name of file to back up to */ 23 void(*xProgress)(int, int) /* Progress function to invoke */ 24 ){ 25 int rc; /* Function return code */ 26 sqlite3 *pFile; /* Database connection opened on zFilename */ 27 sqlite3_backup *pBackup; /* Backup handle used to copy data */ 28 29 /* Open the database file identified by zFilename. */ 30 rc = sqlite3_open(zFilename, &pFile); 31 if( rc==SQLITE_OK ){ 32 33 /* Open the sqlite3_backup object used to accomplish the transfer */ 34 pBackup = sqlite3_backup_init(pFile, "main", pDb, "main"); 35 if( pBackup ){ 36 37 /* Each iteration of this loop copies 5 database pages from database 38 ** pDb to the backup database. If the return value of backup_step() 39 ** indicates that there are still further pages to copy, sleep for 40 ** 250 ms before repeating. */ 41 do { 42 rc = sqlite3_backup_step(pBackup, 5); 43 xProgress( 44 sqlite3_backup_remaining(pBackup), 45 sqlite3_backup_pagecount(pBackup) 46 ); 47 if( rc==SQLITE_OK || rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){ 48 sqlite3_sleep(250); 49 } 50 } while( rc==SQLITE_OK || rc==SQLITE_BUSY || rc==SQLITE_LOCKED ); 51 52 /* Release resources allocated by backup_init(). */ 53 (void)sqlite3_backup_finish(pBackup); 54 } 55 rc = sqlite3_errcode(pFile); 56 } 57 58 /* Close the database connection opened on database file zFilename 59 ** and return the result of this function. */ 60 (void)sqlite3_close(pFile); 61 return rc; 62 }

總結

以上是生活随笔為你收集整理的SQLite学习手册(在线备份)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。