| 1023 | |
| 1024 | |
| 1025 | void BackupImpl::writeFile(const BackupFileInfo & info, BackupEntryPtr entry) |
| 1026 | { |
| 1027 | /// we don't write anything for reference files |
| 1028 | if (entry->isReference()) |
| 1029 | return; |
| 1030 | |
| 1031 | if (entry->isFromRemoteFile()) |
| 1032 | { |
| 1033 | LOG_TRACE(log, "Writing backup for file {} : skipped because of lightweight snapshot", info.data_file_name); |
| 1034 | std::lock_guard lock{mutex}; |
| 1035 | original_endpoint = entry->getEndpointURI(); |
| 1036 | original_namespace = entry->getNamespace(); |
| 1037 | return; |
| 1038 | } |
| 1039 | |
| 1040 | if (open_mode == OpenMode::READ) |
| 1041 | throw Exception(ErrorCodes::LOGICAL_ERROR, "The backup file should not be opened for reading. Something is wrong internally"); |
| 1042 | |
| 1043 | if (writing_finalized) |
| 1044 | throw Exception(ErrorCodes::LOGICAL_ERROR, "Backup is already finalized"); |
| 1045 | |
| 1046 | { |
| 1047 | std::lock_guard lock{mutex}; |
| 1048 | ++num_files; |
| 1049 | total_size += info.size; |
| 1050 | } |
| 1051 | |
| 1052 | auto src_disk = entry->getDisk(); |
| 1053 | auto src_file_path = entry->getFilePath(); |
| 1054 | bool from_immutable_file = entry->isFromImmutableFile(); |
| 1055 | String src_file_desc = src_file_path.empty() ? "memory buffer" : ("file " + src_file_path); |
| 1056 | |
| 1057 | if (info.data_file_name.empty()) |
| 1058 | { |
| 1059 | LOG_TRACE(log, "Writing backup for file {} from {}: skipped, {}", info.data_file_name, src_file_desc, !info.size ? "empty" : "base backup has it"); |
| 1060 | return; |
| 1061 | } |
| 1062 | |
| 1063 | if (!coordination->startWritingFile(info.data_file_index)) |
| 1064 | { |
| 1065 | LOG_TRACE(log, "Writing backup for file {} from {}: skipped, data file #{} is already being written", info.data_file_name, src_file_desc, info.data_file_index); |
| 1066 | return; |
| 1067 | } |
| 1068 | |
| 1069 | if (!lock_file_before_first_file_checked.exchange(true)) |
| 1070 | checkLockFile(true); |
| 1071 | |
| 1072 | /// NOTE: `mutex` must be unlocked during copying otherwise writing will be in one thread maximum and hence slow. |
| 1073 | |
| 1074 | const auto write_info_to_archive = [&](const auto & file_name) |
| 1075 | { |
| 1076 | auto out = archive_writer->writeFile(file_name, info.size); |
| 1077 | auto read_buffer = entry->getReadBuffer(writer->getReadSettings()); |
| 1078 | if (info.base_size != 0) |
| 1079 | read_buffer->seek(info.base_size, SEEK_SET); |
| 1080 | copyData(*read_buffer, *out); |
| 1081 | out->finalize(); |
| 1082 | }; |
no test coverage detected