On 04.01.2011 10:49, Edwin Yip wrote: > Attached an example that reproduces this problem. Your attachment contains a single unit file only. By itself, this does not compile as its corresponding form and project files are missing. I converted your code snippets from Unit1.pas into a console application and was thus able to reproduce your problem. > I hope you can fix it in a quick manner :) The fix is described in the header comment of the attached SQLite_HotBackup_Problem_Fix.dpr file. I have also corrected the code - the project now compiles and runs without errors. Please note that you did not mention the real cause of your problem (SQLite functions called after sqlite3_shutdown) in your initial problem description. Because users are sometimes unaware of the big differences which can result from small code changes, I always insist on fully compilable projects. They are the only reliable way for me to reproduce user's problems exactly as experienced. Ralf
{ This is a fixed console version of the buggy code snippets in Unit1.pas as sent by the original poster. The AV seen by the OP results from the fact that the original code still calls DISQLite3 functions AFTER running sqlite3_shutdown(). According to the documentation, all open database connections must be closed and all other SQLite resources must be deallocated prior to invoking sqlite3_shutdown(). The solution is to move sqlite3_shutdown() to the very end of the application (see below). } program SQLite_HotBackup_Problem_Fix; {$APPTYPE CONSOLE} {$I DI.inc} uses DISystemCompat, SysUtils, DISQLite3Api, DISQLite3Database; function GetCreateDbSqls: UnicodeString; begin Result := 'CREATE TABLE [MyTable] (' + sLineBreak + '[StrField] TEXT);' end; type THotCopyProgressFunc = procedure(const ARemaining, APageCount: Int64); function CopyDatabase( aSrcFile, aDestFile: UnicodeString; aCompressTarget: Boolean = True): Boolean; function l_CopyDatabase( const aSrcDb: sqlite3_ptr; const aDestFileName: Utf8String; const AProgressProc: THotCopyProgressFunc = nil; const ABackupStepPages: Integer = 500; const ABackupSleepPages: Integer = 0): Integer; var cnnDestDb: sqlite3_ptr; { Database connection opened on aDestFileName. } pBackup: sqlite3_backup_ptr; { Backup handle used to copy data. } begin { Open the database file identified by aDestFileName. } Result := sqlite3_open(PUtf8Char(aDestFileName), @cnnDestDb); if Result <> SQLITE_OK then Exit; try { Open the sqlite3_backup object used to accomplish the transfer } pBackup := sqlite3_backup_init(cnnDestDb, 'main', aSrcDb, 'main'); if Assigned(pBackup) then begin try { Each iteration of this loop copies ABackupStepPages database pages from database aSrcDb to the backup database. If the return value of backup_step() indicates that there are still further pages to copy, sleep for SLEEP_MS ms before repeating. } repeat Result := sqlite3_backup_step(pBackup, ABackupStepPages); if Assigned(AProgressProc) then AProgressProc(sqlite3_backup_remaining(pBackup), sqlite3_backup_pagecount(pBackup)); if Result in [SQLITE_OK, SQLITE_BUSY, SQLITE_LOCKED] then sqlite3_sleep(ABackupSleepPages); until not (Result in [SQLITE_OK, SQLITE_BUSY, SQLITE_LOCKED]); finally { Release resources allocated by backup_init(). } sqlite3_backup_finish(pBackup); Result := sqlite3_errcode(cnnDestDb); end; end; finally { Close the database connection opened on database file FileName. } sqlite3_close(cnnDestDb); end; end; var DbSource, dbDest: sqlite3_ptr; utf8SrcFile, utf8DestFile: Utf8String; begin utf8SrcFile := sqlite3_encode_utf8(aSrcFile); utf8DestFile := sqlite3_encode_utf8(aDestFile); { Open the source database file. } sqlite3_check(sqlite3_open_v2(PUtf8Char(utf8SrcFile), @DbSource, SQLITE_OPEN_READONLY, nil)); try { Run the hot copy. } sqlite3_check(l_CopyDatabase(DbSource, utf8DestFile, nil, 500, 0), DbSource); if aCompressTarget then begin { Open the target database file. } sqlite3_check(sqlite3_open(PUtf8Char(utf8DestFile), @dbDest)); try {compress the target db} sqlite3_exec_fast(dbDest, 'VACUUM;'); finally sqlite3_check(sqlite3_close(dbDest), dbDest); end; end; finally { Close the source database file. } sqlite3_check(sqlite3_close(DbSource), DbSource); end; Result := True; end; const conSrcFile = 'test.db3'; var DB: TDISQLite3Database; Stmt: TDISQLite3Statement; begin { Initialize the DISQLite3 library prior to using any other DISQLite3 functionality. See also sqlite3_shutdown() below.} sqlite3_check(sqlite3_initialize); try DB := TDISQLite3Database.Create(nil); DB.DatabaseName := conSrcFile; if not FileExists(DB.DatabaseName) then begin DB.CreateDatabase; DB.Execute(GetCreateDbSqls); end; DB.Open; CopyDatabase(conSrcFile, 'test-copy.db3'); Stmt := DB.Prepare('select * from MyTable'); Stmt.Step; Stmt.Free; FreeAndNil(DB) finally { Deallocate any resources that were allocated by sqlite3_initialize() above. } sqlite3_check(sqlite3_shutdown); end; end.