#include "LocalDbClearThread.h" #include "Logger.h" #include "ProcessConfig.h" #include #include #include #include #include #define SQLITE_DB_LOCK_TIMEOUT 3000 // 세션 중에 SQLITE_BUSY 상황 발생 문제 해결을 위해 DB Lock 관련 timeout 설정값. ( 3 sec ) // 생성자.. CLocalDbClearThread::CLocalDbClearThread() { // Thread Handle 초기화 m_threadHandle = 0; } // 소멸자.. CLocalDbClearThread::~CLocalDbClearThread() { // Thread 가 동작 중인 경우 Thread 동작 정지 처리. if( m_threadHandle != 0 ) pthread_cancel(m_threadHandle); } // Thread 에 정의된 작업을 시작한다... bool CLocalDbClearThread::Start() { int nResult = pthread_create( &m_threadHandle, NULL, CLocalDbClearThread::threadFunc, this ); if( nResult != 0 ) { // Thread 생성 실패시... int errorNum = errno; LOG( LERR, "LocalDbClearThread: Thread create failed.[%d][%s]", errorNum, strerror(errorNum) ); return false; } return true; } // Thread 함수... void * CLocalDbClearThread::threadFunc( void * arg ) { CLocalDbClearThread * pObject = reinterpret_cast(arg); pthread_detach( pthread_self() ); // Local DB 정리 작업은 기동시 1번 수행하고... sleep( 1 ); pthread_testcancel(); pObject->Execute(); pthread_testcancel(); // Thread 종료시 Handle 초기화 pObject->m_threadHandle = 0; return NULL; } // Local DB 정리 작업은 중요도가 낮은 작업이므로... 1일 1회만 수행되도록 한다. void CLocalDbClearThread::Execute() { // 변수 선언 및 초기화.. // Local DB 관련 변수 초기화. sqlite3 * db = NULL; int db_result; int nRetryCount; char szQuery[1024]; char * db_err; // 주기적으로 Local DB 에 대해 // 보관 기간이 초과되었고.... // 전송 처리가 완료된 row 를 삭제 처리한다. while( 1 ) { // Local DB 와 연결을 수행한다. // - Network, Storage 통계 정보 clear 처리 db_result = sqlite3_open( CProcessConfig::GetInstance()->GetLocalDbFileName(), &db ); if( db_result != SQLITE_OK ) { LOG( LERR, "LocalDbClearThread: sqlite3 open failed.[%s][%d][%s]", CProcessConfig::GetInstance()->GetLocalDbFileName(), db_result, sqlite3_errmsg( db ) ); sqlite3_close( db ); db = NULL; } else { // DB File 이 open 된 경우... // 1. network_stat 테이블을 정리한다. // - 각 FHS 로 부터 5분단위로 수신된 정보이므로... FHS 수가 많을 수록 보관량이 많다. // - 따라서 전송되지 않은 정보를 제외하고.. 7 day 지난 row 는 삭제처리한다. (보존기간 7 day, #21025) _LOG( LINF, "LocalDbClearThread: Local DB network_stat table clear start." ); snprintf( szQuery, 1023, "DELETE FROM network_stat WHERE send_flag != 0 AND insert_time < date('now', 'localtime', '-7 day') " ); db_result = sqlite3_exec( db, szQuery, NULL, NULL, &db_err ); nRetryCount = 0; // 만약 BUSY 상태로 인해 오류가 발생하면..10번 재시도 while( db_result == SQLITE_BUSY && nRetryCount < 10 ) { sqlite3_free( db_err ); sqlite3_busy_timeout( db, SQLITE_DB_LOCK_TIMEOUT ); ++nRetryCount; LOG( LWAR, "LocalDbClearThread: local db delete sqlite3_exec SQLITE_BUSY. Retry [%d]", nRetryCount ); // Query 재수행 db_result = sqlite3_exec( db, szQuery, NULL, NULL, &db_err ); } if( db_result != SQLITE_OK ) { LOG( LERR, "LocalDbClearThread: Local DB network_stat table clear failed.[%s][%s]", db_err, szQuery ); sqlite3_free( db_err ); } else { _LOG( LINF, "LocalDbClearThread: Local DB network_stat table clear end. [%d] rows deleted.", sqlite3_changes( db ) ); } // 2. 서비스별 Storage 사용량 정보가 저장된 storage_stat 테이블을 정리한다. // - 각 서비스별로 5분당 1개 Row 가 생성되므로... network_stat 테이블에 비해 row 수가 많지는 않다. // - 따라서 전송되지 않은 정보를 제외하고.. 7 day 지난 row 는 삭제처리한다. (보존기간 7 day, #21025) _LOG( LINF, "LocalDbClearThread: Local DB storage_stat table clear start." ); snprintf( szQuery, 1023, "DELETE FROM storage_stat WHERE send_flag != 0 AND insert_time < date('now', 'localtime', '-7 day') " ); db_result = sqlite3_exec( db, szQuery, NULL, NULL, &db_err ); nRetryCount = 0; // 만약 BUSY 상태로 인해 오류가 발생하면..10번 재시도 while( db_result == SQLITE_BUSY && nRetryCount < 10 ) { sqlite3_free( db_err ); sqlite3_busy_timeout( db, SQLITE_DB_LOCK_TIMEOUT ); ++nRetryCount; LOG( LWAR, "LocalDbClearThread: local db delete sqlite3_exec SQLITE_BUSY. Retry [%d]", nRetryCount ); // Query 재수행 db_result = sqlite3_exec( db, szQuery, NULL, NULL, &db_err ); } if( db_result != SQLITE_OK ) { LOG( LERR, "LocalDbClearThread: Local DB storage_stat table clear failed.[%s][%s]", db_err, szQuery ); sqlite3_free( db_err ); } else { _LOG( LINF, "LocalDbClearThread: Local DB storage_stat table clear end. [%d] rows deleted.", sqlite3_changes( db ) ); } // 3. 최종 Local DB 와의 연결을 해제한다. sqlite3_close( db ); db = NULL; } // 본 루프는 1일 1회만 동작하도록 처리한다. // 24시간 * 60분 * 60 sec = 86400 sleep( 86400 ); } return; }