diff --git a/frameworks/native/dfx/include/rdb_fault_hiview_reporter.h b/frameworks/native/dfx/include/rdb_fault_hiview_reporter.h index 5c3d13004..d08b75b99 100644 --- a/frameworks/native/dfx/include/rdb_fault_hiview_reporter.h +++ b/frameworks/native/dfx/include/rdb_fault_hiview_reporter.h @@ -60,7 +60,7 @@ private: static void DeleteCorruptedFlag(const std::string &dbPath); static std::string GetTimeWithMilliseconds(time_t sec, int64_t nsec); static std::string GetBundleName(const RdbCorruptedEvent &eventInfo); - + static bool HandTimeout(const std::string &dbPath); static Connection::Collector collector_; }; } // namespace OHOS::NativeRdb diff --git a/frameworks/native/dfx/src/rdb_fault_hiview_reporter.cpp b/frameworks/native/dfx/src/rdb_fault_hiview_reporter.cpp index 24703a294..79cd5d6c9 100644 --- a/frameworks/native/dfx/src/rdb_fault_hiview_reporter.cpp +++ b/frameworks/native/dfx/src/rdb_fault_hiview_reporter.cpp @@ -19,9 +19,12 @@ #include #include +#include #include #include +#include #include +#include #include "connection.h" #include "hisysevent_c.h" #include "logger.h" @@ -41,19 +44,38 @@ static constexpr int MAX_TIME_BUF_LEN = 32; static constexpr int MILLISECONDS_LEN = 3; static constexpr int NANO_TO_MILLI = 1000000; static constexpr int MILLI_PRE_SEC = 1000; +static constexpr int TIME_OUT_MINUTES = 10; +static std::unordered_map dbfileLastTimeStatistical_; +static std::mutex dbfilesMutex_; Connection::Collector RdbFaultHiViewReporter::collector_ = nullptr; void RdbFaultHiViewReporter::ReportFault(const RdbCorruptedEvent &eventInfo) { + RdbCorruptedEvent eventInfoAppend = eventInfo; + if (HandTimeout(eventInfo.path)) { + for (auto &[name, debugInfo] : eventInfo.debugInfos) { + eventInfoAppend.appendix += "\n" + name + " :" + GetFileStatInfo(debugInfo); + } + LOG_WARN("database corrupted store:%{public}s, errCode:%{public}d, append:%{public}s", + SqliteUtils::Anonymous(eventInfo.storeName).c_str(), + eventInfo.errorCode, + eventInfoAppend.appendix.c_str()); + } if (IsReportCorruptedFault(eventInfo.path)) { - Report(eventInfo); + Report(eventInfoAppend); CreateCorruptedFlag(eventInfo.path); } } void RdbFaultHiViewReporter::ReportRestore(const RdbCorruptedEvent &eventInfo) { - Report(eventInfo); + RdbCorruptedEvent eventInfoAppend = eventInfo; + for (auto &[name, debugInfo] : eventInfo.debugInfos) { + eventInfoAppend.appendix += "\n" + name + " :" + GetFileStatInfo(debugInfo); + } + LOG_INFO("database restore store:%{public}s, errCode:%{public}d, append:%{public}s", + SqliteUtils::Anonymous(eventInfo.storeName).c_str(), eventInfo.errorCode, eventInfoAppend.appendix.c_str()); + Report(eventInfoAppend); DeleteCorruptedFlag(eventInfo.path); } @@ -65,11 +87,6 @@ void RdbFaultHiViewReporter::Report(const RdbCorruptedEvent &eventInfo) std::string storeName = eventInfo.storeName; uint32_t checkType = eventInfo.integrityCheck; std::string appendInfo = eventInfo.appendix; - for (auto &[name, debugInfo] : eventInfo.debugInfos) { - appendInfo += "\n" + name + " :" + GetFileStatInfo(debugInfo); - } - LOG_WARN("storeName: %{public}s, errorCode: %{public}d, appendInfo : %{public}s", - SqliteUtils::Anonymous(eventInfo.storeName).c_str(), eventInfo.errorCode, appendInfo.c_str()); std::string occurTime = GetTimeWithMilliseconds(eventInfo.errorOccurTime, 0); char *errorOccurTime = occurTime.data(); HiSysEventParam params[] = { @@ -93,14 +110,14 @@ std::string RdbFaultHiViewReporter::GetFileStatInfo(const DebugInfo &debugInfo) { std::stringstream oss; const uint32_t permission = 0777; - oss << " device: 0x" << std::hex << debugInfo.dev_ << " inode: 0x" << std::hex << debugInfo.inode_; + oss << " dev:0x" << std::hex << debugInfo.dev_ << " ino:0x" << std::hex << debugInfo.inode_; if (debugInfo.inode_ != debugInfo.oldInode_ && debugInfo.oldInode_ != 0) { oss << "<>0x" << std::hex << debugInfo.oldInode_; } - oss << " mode: 0" << std::oct << (debugInfo.mode_ & permission) << " size: " << std::dec << debugInfo.size_ - << " natime: " << GetTimeWithMilliseconds(debugInfo.atime_.sec_, debugInfo.atime_.nsec_) - << " smtime: " << GetTimeWithMilliseconds(debugInfo.mtime_.sec_, debugInfo.mtime_.nsec_) - << " sctime: " << GetTimeWithMilliseconds(debugInfo.ctime_.sec_, debugInfo.ctime_.nsec_); + oss << " mode:0" << std::oct << (debugInfo.mode_ & permission) << " size:" << std::dec << debugInfo.size_ + << " atim:" << GetTimeWithMilliseconds(debugInfo.atime_.sec_, debugInfo.atime_.nsec_) + << " mtim:" << GetTimeWithMilliseconds(debugInfo.mtime_.sec_, debugInfo.mtime_.nsec_) + << " ctim:" << GetTimeWithMilliseconds(debugInfo.ctime_.sec_, debugInfo.ctime_.nsec_); return oss.str(); } @@ -156,6 +173,22 @@ std::string RdbFaultHiViewReporter::GetTimeWithMilliseconds(time_t sec, int64_t return oss.str(); } +bool RdbFaultHiViewReporter::HandTimeout(const std::string &dbPath) +{ + std::lock_guard lock(dbfilesMutex_); + auto now = std::chrono::steady_clock::now(); + if (dbfileLastTimeStatistical_.find(dbPath) != dbfileLastTimeStatistical_.end()) { + auto lastTime = dbfileLastTimeStatistical_[dbPath]; + auto duration = std::chrono::duration_cast(now - lastTime); + if (duration.count() < TIME_OUT_MINUTES) { + return false; + } + } + LOG_DEBUG("dbPath %{public}s Last Time is update", SqliteUtils::Anonymous(dbPath).c_str()); + dbfileLastTimeStatistical_[dbPath] = now; + return true; +} + RdbCorruptedEvent RdbFaultHiViewReporter::Create(const RdbStoreConfig &config, int32_t errCode, const std::string &appendix) { diff --git a/frameworks/native/rdb/include/sqlite_statement.h b/frameworks/native/rdb/include/sqlite_statement.h index c7ddb2738..5ab28c4ad 100644 --- a/frameworks/native/rdb/include/sqlite_statement.h +++ b/frameworks/native/rdb/include/sqlite_statement.h @@ -87,7 +87,7 @@ private: int InnerFinalize(); ValueObject GetValueFromBlob(int32_t index, int32_t type) const; void ReadFile2Buffer(); - void PrintInfoForDbError(int errorCode, const std::string &sql); + void PrintInfoForDbError(int errCode, const std::string &sql); static constexpr uint32_t BUFFER_LEN = 16; diff --git a/frameworks/native/rdb/mock/src/rdb_fault_hiview_reporter.cpp b/frameworks/native/rdb/mock/src/rdb_fault_hiview_reporter.cpp index e8f93f8dd..4ca533b0f 100644 --- a/frameworks/native/rdb/mock/src/rdb_fault_hiview_reporter.cpp +++ b/frameworks/native/rdb/mock/src/rdb_fault_hiview_reporter.cpp @@ -82,4 +82,9 @@ std::string RdbFaultHiViewReporter::GetBundleName(const RdbCorruptedEvent &event (void)eventInfo; return ""; } + +bool RdbFaultHiViewReporter::HandTimeout(const std::string &dbPath) +{ + return false; +} } // namespace OHOS::NativeRdb \ No newline at end of file diff --git a/frameworks/native/rdb/src/connection_pool.cpp b/frameworks/native/rdb/src/connection_pool.cpp index 900b0db2f..0ceeb10a8 100644 --- a/frameworks/native/rdb/src/connection_pool.cpp +++ b/frameworks/native/rdb/src/connection_pool.cpp @@ -27,6 +27,7 @@ #include "connection.h" #include "rdb_common.h" #include "rdb_errno.h" +#include "rdb_fault_hiview_reporter.h" #include "rdb_sql_statistic.h" #include "sqlite_global_config.h" #include "sqlite_utils.h" @@ -78,6 +79,8 @@ std::pair> ConnPool::HandleDataCorr LOG_WARN("failed, type %{public}d db %{public}s encrypt %{public}d error %{public}d, errno", static_cast(rebuiltType), SqliteUtils::Anonymous(storeConfig.GetName()).c_str(), storeConfig.IsEncrypt(), errCode, errno); + } else { + RdbFaultHiViewReporter::ReportRestore(RdbFaultHiViewReporter::Create(storeConfig, E_OK)); } return result; diff --git a/frameworks/native/rdb/src/rdb_store_impl.cpp b/frameworks/native/rdb/src/rdb_store_impl.cpp index d7e8b27e9..ea805d0e6 100644 --- a/frameworks/native/rdb/src/rdb_store_impl.cpp +++ b/frameworks/native/rdb/src/rdb_store_impl.cpp @@ -318,6 +318,7 @@ RdbStoreImpl::RdbStoreImpl(const RdbStoreConfig &config, int &errCode) service->Disable(param); } #endif + config_.SetIter(0); std::tie(rebuild_, connectionPool_) = ConnectionPool::HandleDataCorruption(config_, errCode); created = true; #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) diff --git a/frameworks/native/rdb/src/sqlite_statement.cpp b/frameworks/native/rdb/src/sqlite_statement.cpp index 8bab59ec1..cb32b58ca 100644 --- a/frameworks/native/rdb/src/sqlite_statement.cpp +++ b/frameworks/native/rdb/src/sqlite_statement.cpp @@ -76,7 +76,8 @@ int SqliteStatement::Prepare(sqlite3 *dbHandle, const std::string &newSql) ReadFile2Buffer(); } int ret = SQLiteError::ErrNo(errCode); - if (ret == E_SQLITE_CORRUPT && config_ != nullptr) { + if (config_ != nullptr && + (errCode == SQLITE_CORRUPT || (errCode == SQLITE_NOTADB && config_->GetIter() != 0))) { RdbFaultHiViewReporter::ReportFault(RdbFaultHiViewReporter::Create(*config_, ret)); } PrintInfoForDbError(ret, newSql); @@ -92,17 +93,19 @@ int SqliteStatement::Prepare(sqlite3 *dbHandle, const std::string &newSql) return E_OK; } -void SqliteStatement::PrintInfoForDbError(int errorCode, const std::string &sql) +void SqliteStatement::PrintInfoForDbError(int errCode, const std::string &sql) { if (config_ == nullptr) { return; } - if (errorCode == E_SQLITE_ERROR && sql == std::string(GlobalExpr::PRAGMA_VERSION) + "=?") { + + if (errCode == E_SQLITE_ERROR && sql == std::string(GlobalExpr::PRAGMA_VERSION) + "=?") { return; } - if (errorCode == E_SQLITE_ERROR || errorCode == E_SQLITE_BUSY || errorCode == E_SQLITE_LOCKED || - errorCode == E_SQLITE_IOERR || errorCode == E_SQLITE_CORRUPT || errorCode == E_SQLITE_CANTOPEN) { - LOG_ERROR(" DbError errorCode: %{public}d DbName: %{public}s ", errorCode, + + if (errCode == E_SQLITE_ERROR || errCode == E_SQLITE_BUSY || errCode == E_SQLITE_LOCKED || + errCode == E_SQLITE_IOERR || errCode == E_SQLITE_CANTOPEN) { + LOG_ERROR("DbError errCode:%{public}d errno:%{public}d DbName: %{public}s ", errCode, errno, SqliteUtils::Anonymous(config_->GetName()).c_str()); } } @@ -282,8 +285,9 @@ int SqliteStatement::Step() int SqliteStatement::InnerStep() { SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_EXECUTE, seqId_); - int ret = SQLiteError::ErrNo(sqlite3_step(stmt_)); - if (ret == E_SQLITE_CORRUPT && config_ != nullptr) { + auto errCode = sqlite3_step(stmt_); + int ret = SQLiteError::ErrNo(errCode); + if (config_ != nullptr && (errCode == SQLITE_CORRUPT || (errCode == SQLITE_NOTADB && config_->GetIter() != 0))) { RdbFaultHiViewReporter::ReportFault(RdbFaultHiViewReporter::Create(*config_, ret)); } PrintInfoForDbError(ret, sql_);