1. 데이터베이스 lock
2. 일부 데이터 백업
3. 데이터베이스 unlock
4. 남은 데이터가 있으면 잠시 대기 후 1번 과정으로 반복
그런데 이와 같은 방식으로 백업을 하면 시간이 오래 걸리는데, 중간에 다른 프로세스에서 해당 데이터베이스에 새로운 데이터를 기록하면 자동으로 백업을 멈추고 처음부터 다시 시작하게 된다. 따라서 계속 바쁘게 사용하는 시스템에 이 방법을 사용하면 백업이 영원히 종료되지 않는 문제가 생길 수 있다.
아래 코드는 SQLite 사이트에 있는 샘플 코드를 사용해서 첫번째 방법(한번에 모두 백업)으로 간단하게 백업툴을 만든 것이다.
/*
* SQLite3 Online Backup Tool
*
* Kitae Kim <superkkt@sds.co.kr>
*
* <Compile Instruction>
* $ sudo apt-get install libsqlite3-dev
* $ g++ -Wall -O2 -o sqlite_online_backup sqlite_online_backup.cpp -lsqlite3
*/
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <sqlite3.h>
/*
** 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;
}
int main(int argc, char **argv)
{
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " db_file backup_file\n";
exit(EXIT_FAILURE);
}
sqlite3 *db = NULL;
if (sqlite3_open(argv[1], &db) != SQLITE_OK) {
std::cerr << "Failed to open the database file..\n";
exit(EXIT_FAILURE);
}
int rc = loadOrSaveDb(db, argv[2], 1);
if (rc != SQLITE_OK) {
(void) sqlite3_close(db);
std::cerr << "Failed to backup the database file.. (errno: " << rc << ")\n";
exit(EXIT_FAILURE);
}
(void) sqlite3_close(db);
return 0;
}
* SQLite3 Online Backup Tool
*
* Kitae Kim <superkkt@sds.co.kr>
*
* <Compile Instruction>
* $ sudo apt-get install libsqlite3-dev
* $ g++ -Wall -O2 -o sqlite_online_backup sqlite_online_backup.cpp -lsqlite3
*/
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <sqlite3.h>
/*
** 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;
}
int main(int argc, char **argv)
{
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " db_file backup_file\n";
exit(EXIT_FAILURE);
}
sqlite3 *db = NULL;
if (sqlite3_open(argv[1], &db) != SQLITE_OK) {
std::cerr << "Failed to open the database file..\n";
exit(EXIT_FAILURE);
}
int rc = loadOrSaveDb(db, argv[2], 1);
if (rc != SQLITE_OK) {
(void) sqlite3_close(db);
std::cerr << "Failed to backup the database file.. (errno: " << rc << ")\n";
exit(EXIT_FAILURE);
}
(void) sqlite3_close(db);
return 0;
}

comments
comments rss (+댓글 쓰러가기)