SQLite 자습서(9): 온라인 백업
다음 방법은 비교적 간단하고 자주 사용하는 SQLite 데이터베이스 백업 방식입니다. 다음 절차를 보십시오.
1). SQLite API 또는 Shell 도구를 사용하여 소스 데이터베이스 파일에 공유 잠금을 추가합니다.
2). Shell 도구(cp 또는copy)를 사용하여 데이터베이스 파일을 백업 디렉토리로 복사합니다.
3). 데이터베이스 파일의 공유 잠금을 해제합니다.
상기 3단계는 대부분의 장면에 적용될 수 있고 속도도 비교적 빠르지만 일정한 강성 결함이 존재한다. 예를 들어 다음과 같다.
1). 전체 복사 프로세스가 끝나고 파일 공유 잠금이 해제될 때까지 원본 데이터베이스에서 쓰기 작업을 수행하려는 모든 연결이 끊어져야 합니다.
2). 인메모리 데이터베이스에 데이터를 복사할 수 없습니다.
3). 복사 과정에서 백업 데이터베이스가 있는 호스트에 돌발적인 고장이 발생하면 백업 데이터베이스가 파괴될 수 있다.
SQLite에서 온라인 데이터베이스 백업에 사용할 API 함수(C 인터페이스)를 제공하여 상술한 방법의 부족함을 잘 해결할 수 있습니다.이 그룹 함수를 통해 원본 데이터베이스의 내용을 다른 데이터베이스로 복사하고 대상 데이터베이스의 데이터를 덮어쓸 수 있습니다.전체 복사 과정은 증량적인 방식으로 완성될 수 있으며, 이 경우 원본 데이터베이스도 전체 복사 과정에서 잠기지 않고 실제 데이터를 읽을 때 공유 잠금을 추가할 필요가 없다.이렇게 하면 다른 사용자가 원본 데이터베이스에 접근할 때 끊기지 않는다.
2. 온라인 백업 API 소개:
SQLite는 이 동작을 완성하기 위해 다음과 같은 3개의 API 함수를 제공합니다. 여기에서 기본적인 사용법만 제시하고 사용 세부 사항은 SQLite 공식 사이트'API Reference'http://www.sqlite.org/c3ref/backup_finish.html를 참조하십시오.
1). 함수 sqlite3_backup_init() sqlite3_ 만들기백업 대상, 이 대상은 이번 복사 작업의 핸들로 나머지 두 함수에 전달됩니다.
2). 함수 sqlite3_backup_step () 는 데이터 복사에 사용됩니다. 만약에 이 함수의 두 번째 매개 변수가 -1이라면 전체 복사 과정은 이 함수의 호출에서 완성됩니다.
3). 함수 sqlite3_backup_finish() sqlite3_ 방출backup_자원 유출을 피하기 위해 init () 함수로 신청한 자원입니다.
전체 복사 과정에서 오류가 발생하면 목적 데이터베이스로 연결된 sqlite3_errcode () 함수는 구체적인 오류 코드를 가져옵니다.또한 sqlite3_backup_step () 호출 실패, sqlite3_backup_finish () 함수는 현재 연결된 오류 코드를 수정하지 않기 때문에 sqlite3_backup_finish () 다음에 오류 코드를 가져와서 코드에서 오류 처리를 줄였습니다.다음 코드 예제 (SQLite 공식 홈페이지에서 제공) 를 참조하십시오.
/*
** This function is used to load the contents of a database file on disk
** into the "main" database of open database connection pInMemory, or
** to save the current contents of the database opened by pInMemory into
** a database file on disk. pInMemory is probably an in-memory database,
** but this function will also work fine if it is not.
**
** Parameter zFilename points to a nul-terminated string containing the
** name of the database file on disk to load from or save to. If parameter
** isSave is non-zero, then the contents of the file zFilename are
** overwritten with the contents of the database opened by pInMemory. If
** parameter isSave is zero, then the contents of the database opened by
** pInMemory are replaced by data loaded from the file zFilename.
**
** If the operation is successful, SQLITE_OK is returned. Otherwise, if
** an error occurs, an SQLite error code is returned.
*/
int loadOrSaveDb(sqlite3 *pInMemory, const char *zFilename, int isSave){
int rc; /* Function return code */
sqlite3 *pFile; /* Database connection opened on zFilename */
sqlite3_backup *pBackup; /* Backup object used to copy data */
sqlite3 *pTo; /* Database to copy to (pFile or pInMemory) */
sqlite3 *pFrom; /* Database to copy from (pFile or pInMemory) */
/* Open the database file identified by zFilename. Exit early if this fails
** for any reason. */
rc = sqlite3_open(zFilename, &pFile);
if( rc==SQLITE_OK ){
/* If this is a 'load' operation (isSave==0), then data is copied
** from the database file just opened to database pInMemory.
** Otherwise, if this is a 'save' operation (isSave==1), then data
** is copied from pInMemory to pFile. Set the variables pFrom and
** pTo accordingly. */
pFrom = (isSave ? pInMemory : pFile);
pTo = (isSave ? pFile : pInMemory);
/* Set up the backup procedure to copy from the "main" database of
** connection pFile to the main database of connection pInMemory.
** If something goes wrong, pBackup will be set to NULL and an error
** code and message left in connection pTo.
**
** If the backup object is successfully created, call backup_step()
** to copy data from pFile to pInMemory. Then call backup_finish()
** to release resources associated with the pBackup object. If an
** error occurred, then an error code and message will be left in
** connection pTo. If no error occurred, then the error code belonging
** to pTo is set to SQLITE_OK.
*/
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);
}
/* Close the database connection opened on database file zFilename
** and return the result of this function. */
(void)sqlite3_close(pFile);
return rc;
}
3. 고급 응용 기술:위의 예에서 우리는 sqlite3_를 통해backup_step () 함수의 호출로 전체 복사 과정이 완료되었습니다.이 실현 방식은 이전에 말한 다른 쓰기 액세스 연결을 끊는 문제가 여전히 존재하기 때문에 이 문제를 해결하기 위해 다음과 같은 단계의 다른 고급 실현 방식인 분할 복사를 계속 소개할 것입니다.
1). 함수 sqlite3_backup_init() sqlite3_ 만들기백업 대상, 이 대상은 이번 복사 작업의 핸들로 나머지 두 함수에 전달됩니다.
2). 함수 sqlite3_backup_step () 는 데이터 복사에 호출됩니다. 이전 방법과 달리 이 함수의 두 번째 매개 변수는 -1이 아니라 일반적인 정수입니다. 호출할 때마다 복사할 페이지의 수량을 나타냅니다. 예를 들어 5.
3). 하면, 만약, 만약...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_이 중 전자는 현재 백업 작업에서 복사해야 할 페이지가 얼마나 많은지, 후자는 이번 작업에서 복사해야 할 페이지 수를 되돌려줍니다.이 두 함수의 반환 결과를 통해 이 백업 작업의 전체 진행 상황을 실시간으로 보여 줍니다. 계산 공식은 다음과 같습니다.
Completion = 100% * (pagecount() - remaining())/pagecount()
다음 코드 예제 (SQLite 공식 홈페이지에서 제공) 를 참조하십시오.
/*
** Perform an online backup of database pDb to the database file named
** by zFilename. This function copies 5 database pages from pDb to
** zFilename, then unlocks pDb and sleeps for 250 ms, then repeats the
** process until the entire database is backed up.
**
** The third argument passed to this function must be a pointer to a progress
** function. After each set of 5 pages is backed up, the progress function
** is invoked with two integer parameters: the number of pages left to
** copy, and the total number of pages in the source file. This information
** may be used, for example, to update a GUI progress bar.
**
** While this function is running, another thread may use the database pDb, or
** another process may access the underlying database file via a separate
** connection.
**
** If the backup process is successfully completed, SQLITE_OK is returned.
** Otherwise, if an error occurs, an SQLite error code is returned.
*/
int backupDb(
sqlite3 *pDb, /* Database to back up */
const char *zFilename, /* Name of file to back up to */
void(*xProgress)(int, int) /* Progress function to invoke */
){
int rc; /* Function return code */
sqlite3 *pFile; /* Database connection opened on zFilename */
sqlite3_backup *pBackup; /* Backup handle used to copy data */
/* Open the database file identified by zFilename. */
rc = sqlite3_open(zFilename, &pFile);
if( rc==SQLITE_OK ){
/* Open the sqlite3_backup object used to accomplish the transfer */
pBackup = sqlite3_backup_init(pFile, "main", pDb, "main");
if( pBackup ){
/* Each iteration of this loop copies 5 database pages from database
** pDb to the backup database. If the return value of backup_step()
** indicates that there are still further pages to copy, sleep for
** 250 ms before repeating. */
do {
rc = sqlite3_backup_step(pBackup, 5);
xProgress(
sqlite3_backup_remaining(pBackup),
sqlite3_backup_pagecount(pBackup)
);
if( rc==SQLITE_OK || rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
sqlite3_sleep(250);
}
} while( rc==SQLITE_OK || rc==SQLITE_BUSY || rc==SQLITE_LOCKED );
/* Release resources allocated by backup_init(). */
(void)sqlite3_backup_finish(pBackup);
}
rc = sqlite3_errcode(pFile);
}
/* Close the database connection opened on database file zFilename
** and return the result of this function. */
(void)sqlite3_close(pFile);
return rc;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
SQLite 데이터베이스 설치 및 기본 운영 설명서대부분의 경우 - SQLite의 바이너리 파일이 존재하는지 확인하면 데이터베이스를 만들고 연결하며 사용할 수 있다.내장형 데이터베이스 항목이나 솔루션을 찾고 있다면 SQLite는 매우 고려할 만합니다. SQLite ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.