diff --git a/base/base/LocalDateTime.h b/base/base/LocalDateTime.h index 0edc12374bb..282a56ac640 100644 --- a/base/base/LocalDateTime.h +++ b/base/base/LocalDateTime.h @@ -108,6 +108,11 @@ public: LocalDate toDate() const { return LocalDate(m_year, m_month, m_day); } LocalDateTime toStartOfDate() const { return LocalDateTime(m_year, m_month, m_day, 0, 0, 0); } + time_t to_time_t(const DateLUTImpl & time_zone = DateLUT::instance()) const + { + return time_zone.makeDateTime(m_year, m_month, m_day, m_hour, m_minute, m_second); + } + std::string toString() const { std::string s{"0000-00-00 00:00:00"}; diff --git a/src/Backups/BackupInDirectory.cpp b/src/Backups/BackupInDirectory.cpp index 7e61cbdba2e..ecd92fe3724 100644 --- a/src/Backups/BackupInDirectory.cpp +++ b/src/Backups/BackupInDirectory.cpp @@ -86,6 +86,9 @@ void BackupInDirectory::open() disk->createDirectories(path); directory_was_created = true; } + + timestamp = std::time(nullptr); + uuid = UUIDHelpers::generateV4(); } if (open_mode == OpenMode::READ) @@ -102,6 +105,12 @@ void BackupInDirectory::open() params.open_mode = OpenMode::READ; params.context = context; base_backup = BackupFactory::instance().createBackup(params); + + if (open_mode == OpenMode::WRITE) + base_backup_uuid = base_backup->getUUID(); + else if (base_backup_uuid != base_backup->getUUID()) + throw Exception(ErrorCodes::WRONG_BASE_BACKUP, "Backup {}: The base backup {} has different UUID ({} != {})", + getName(), base_backup->getName(), toString(base_backup->getUUID()), (base_backup_uuid ? toString(*base_backup_uuid) : "")); } } @@ -122,9 +131,13 @@ void BackupInDirectory::writeMetadata() { Poco::AutoPtr config{new Poco::Util::XMLConfiguration()}; config->setUInt("version", BACKUP_VERSION); + config->setString("timestamp", toString(LocalDateTime{timestamp})); + config->setString("uuid", toString(uuid)); if (base_backup_info) config->setString("base_backup", base_backup_info->toString()); + if (base_backup_uuid) + config->setString("base_backup_uuid", toString(*base_backup_uuid)); size_t index = 0; for (const auto & [name, info] : infos) @@ -160,12 +173,18 @@ void BackupInDirectory::readMetadata() Poco::AutoPtr config{new Poco::Util::XMLConfiguration()}; config->load(stream); - UInt64 version = config->getUInt("version", 1); + UInt64 version = config->getUInt("version"); if (version != BACKUP_VERSION) throw Exception(ErrorCodes::BACKUP_VERSION_NOT_SUPPORTED, "Backup {}: Version {} is not supported", getName(), version); + timestamp = parse(config->getString("timestamp")).to_time_t(); + uuid = parse(config->getString("uuid")); + if (config->has("base_backup") && !base_backup_info) - base_backup_info.emplace(BackupInfo::fromString(config->getString("base_backup"))); + base_backup_info = BackupInfo::fromString(config->getString("base_backup")); + + if (config->has("base_backup_uuid") && !base_backup_uuid) + base_backup_uuid = parse(config->getString("base_backup_uuid")); infos.clear(); Poco::Util::AbstractConfiguration::Keys keys; diff --git a/src/Backups/BackupInDirectory.h b/src/Backups/BackupInDirectory.h index 14cb1f82f39..16a48f3690c 100644 --- a/src/Backups/BackupInDirectory.h +++ b/src/Backups/BackupInDirectory.h @@ -33,6 +33,8 @@ public: const String & getName() const override { return backup_name; } OpenMode getOpenMode() const override { return open_mode; } + time_t getTimestamp() const override { return timestamp; } + UUID getUUID() const override { return uuid; } Strings list(const String & prefix, const String & terminator) const override; bool exists(const String & name) const override; size_t getSize(const String & name) const override; @@ -59,11 +61,14 @@ private: const String backup_name; const OpenMode open_mode; + UUID uuid; + time_t timestamp; DiskPtr disk; String path; ContextPtr context; std::optional base_backup_info; std::shared_ptr base_backup; + std::optional base_backup_uuid; std::map infos; bool directory_was_created = false; bool finalized = false; diff --git a/src/Backups/IBackup.h b/src/Backups/IBackup.h index 0130665a343..8a6020a604e 100644 --- a/src/Backups/IBackup.h +++ b/src/Backups/IBackup.h @@ -31,6 +31,12 @@ public: /// A backup can be open either in READ or WRITE mode. virtual OpenMode getOpenMode() const = 0; + /// Returns the time point when this backup was created. + virtual time_t getTimestamp() const = 0; + + /// Returns UUID of the backup. + virtual UUID getUUID() const = 0; + /// Returns names of entries stored in the backup. /// If `prefix` isn't empty the function will return only the names starting with /// the prefix (but without the prefix itself).