From d21e412dbc6f2cdde2e4c9828e2450fcfca4fbe9 Mon Sep 17 00:00:00 2001 From: ryne3366 Date: Tue, 18 Feb 2025 11:43:37 +0800 Subject: [PATCH] Backup step support restore meta pages Signed-off-by: ryne3366 --- src/sqlite3.c | 92 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 80 insertions(+), 12 deletions(-) diff --git a/src/sqlite3.c b/src/sqlite3.c index 1188d1c..d4048c9 100644 --- a/src/sqlite3.c +++ b/src/sqlite3.c @@ -56096,6 +56096,10 @@ struct PagerSavepoint { #endif }; +#if !defined(SQLITE_OS_UNIX) && defined(SQLITE_META_DWR) +#undef SQLITE_META_DWR +#endif + #ifdef SQLITE_META_DWR static int PragmaMetaDoubleWrie(sqlite3 *db, int iDb, Parse *parse, const char *zLeft, const char *zRight); typedef struct MetaDwrHdr MetaDwrHdr; @@ -56106,6 +56110,7 @@ static int MetaDwrOpenFile(Pager *pPager, u8 openCreate); static void MetaDwrCheckVacuum(BtShared *pBt); static int MetaDwrRecoverAndBeginTran(Btree *pBt, int wrflag, int *pSchemaVersion); static int MetaDwrOpenAndCheck(Btree *pBt); +static void MetaDwrDisable(Btree *pBt); #define META_HEADER_CHANGED 1 #define META_SCHEMA_CHANGED 2 #define META_IN_RECOVERY 1 @@ -68351,7 +68356,6 @@ struct BtShared { u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */ int nPreformatSize; /* Size of last cell written by TransferRow() */ #ifdef SQLITE_META_DWR - u32 metaFileChecked; u32 maxMetaPage; u32 metaRecoverStatus; #endif @@ -80991,6 +80995,12 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ } } } + #ifdef SQLITE_META_DWR + if (rc == SQLITE_OK && p->pDest->pBt->pPager->metaFd) { + p->pDest->pBt->pPager->metaChanged = META_SCHEMA_CHANGED; + (void)MetaDwrUpdateMetaPages(p->pDest); + } + #endif if( rc==SQLITE_OK ){ rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1); } @@ -81021,6 +81031,12 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ } }else{ sqlite3PagerTruncateImage(pDestPager, nDestTruncate); + #ifdef SQLITE_META_DWR + if (rc == SQLITE_OK && p->pDest->pBt->pPager->metaFd) { + p->pDest->pBt->pPager->metaChanged = META_SCHEMA_CHANGED; + (void)MetaDwrUpdateMetaPages(p->pDest); + } + #endif rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0); } @@ -246206,6 +246222,10 @@ static int PragmaMetaDoubleWrie(sqlite3 *db, int iDb, Parse *parse, const char * parse->rc = rc; } sqlite3_mutex_leave(db->mutex); + } else if (strncmp(zRight, "disabled", 8) == 0) { + sqlite3_mutex_enter(db->mutex); + MetaDwrDisable(pBt); + sqlite3_mutex_leave(db->mutex); } return 1; } @@ -246409,14 +246429,17 @@ static void MetaDwrCloseFile(Pager *pPager) { if (pPager->metaHdr && pPager->metaHdr->needSync > 0) { (void)sqlite3OsSync(pPager->metaFd, SQLITE_SYNC_NORMAL); } - sqlite3OsCloseFree(pPager->metaFd); - pPager->metaFd = NULL; + sqlite3OsClose(pPager->metaFd); } static void MetaDwrPagerRelease(Pager *pPager) { MetaDwrCloseFile(pPager); MetaDwrReleaseHdr(pPager->metaHdr); pPager->metaHdr = NULL; + if (pPager->metaFd) { + sqlite3_free(pPager->metaFd); + pPager->metaFd = NULL; + } } static inline int ReadFromHdrPage(Pager *pPager, void *data, int amt, i64 offset) { @@ -246641,6 +246664,11 @@ static int MetaDwrRestoreAllPages(Btree *pBt, const ScanPages *metaPages, MetaDw return rc; } +static inline const char *GetMetaFilePath(Pager *pPager) +{ + return pPager->metaFd == NULL ? NULL : ((const char *)pPager->metaFd + ROUND8(pPager->pVfs->szOsFile)); +} + static int MetaDwrOpenFile(Pager *pPager, u8 openCreate) { if (pPager->metaFd || pPager->zFilename == NULL) { return SQLITE_OK; @@ -246648,11 +246676,12 @@ static int MetaDwrOpenFile(Pager *pPager, u8 openCreate) { sqlite3BeginBenignMalloc(); sqlite3_vfs *pVfs = pPager->pVfs; int size = strlen(pPager->zFilename) + sizeof("-dwr"); - sqlite3_file *metaFd = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile + size); - char *metaPath = (char *)metaFd + pVfs->szOsFile; + int szOsFile = ROUND8(pVfs->szOsFile); + sqlite3_file *metaFd = (sqlite3_file *)sqlite3MallocZero(szOsFile + size); + char *metaPath = (char *)metaFd + szOsFile; if (metaFd == NULL) { sqlite3EndBenignMalloc(); - sqlite3_log(SQLITE_NOMEM_BKPT, "sqlite alloc memsize %d go wrong", size); + sqlite3_log(SQLITE_NOMEM_BKPT, "sqlite alloc memsize %d go wrong", szOsFile + size); return SQLITE_NOMEM_BKPT; } sqlite3_snprintf(size, metaPath, "%s-dwr", pPager->zFilename); @@ -247053,9 +247082,25 @@ CHK_RESTORE_OUT: return rc; } -static int MetaDwrOpenAndCheck(Btree *pBt) { +static inline u8 IsConnectionValidForCheck(Pager *pPager) +{ +#if SQLITE_OS_UNIX + unixFile *fd = (unixFile *)pPager->fd; + // unix and only one connection exist + if (fd == NULL || fd->pInode == NULL || pPager->pVfs == NULL || + sqlite3_stricmp(pPager->pVfs->zName, "unix") != 0 || fd->pInode->nRef != 1) { + return 0; + } + return 1; +#else + return 0; +#endif +} + +static int MetaDwrOpenAndCheck(Btree *pBt) +{ Pager *pPager = pBt->pBt->pPager; - if (pPager->memDb || pPager->readOnly) { + if (pPager->memDb || pPager->readOnly || !IsConnectionValidForCheck(pPager)) { return SQLITE_OK; } #ifdef SQLITE_HAS_CODEC @@ -247064,9 +247109,6 @@ static int MetaDwrOpenAndCheck(Btree *pBt) { return SQLITE_OK; } #endif - if (pPager->metaFd != NULL && pBt->pBt->metaFileChecked) { - return SQLITE_OK; - } sqlite3BtreeEnter(pBt); int rc = SQLITE_OK; int openedTransaction = 0; @@ -247097,9 +247139,35 @@ DWR_OPEN_OUT: sqlite3BtreeCommit(pBt); } sqlite3BtreeLeave(pBt); - pBt->pBt->metaFileChecked = 1; return rc; } + +static void MetaDwrDisable(Btree *pBt) +{ + Pager *pPager = pBt->pBt->pPager; + if (pPager->metaFd == NULL || pPager->memDb || pPager->readOnly || !IsConnectionValidForCheck(pPager)) { + return; + } +#ifdef SQLITE_HAS_CODEC + // not support codec right now + if (pPager->xCodec) { + return; + } +#endif + sqlite3BtreeEnter(pBt); + MetaDwrCloseFile(pPager); + MetaDwrReleaseHdr(pPager->metaHdr); + pPager->metaHdr = NULL; + const char *metaPath = GetMetaFilePath(pPager); + if (metaPath != NULL) { + (void)osUnlink(metaPath); + } + if (pPager->metaFd) { + sqlite3_free(pPager->metaFd); + pPager->metaFd = NULL; + } + sqlite3BtreeLeave(pBt); +} #endif #if SQLITE_OS_UNIX #include -- Gitee