@ -14,6 +14,7 @@
# include <algorithm>
# include <algorithm>
# include <cinttypes>
# include <cinttypes>
# include <string>
# include <string>
# include <tuple>
# include <vector>
# include <vector>
# include "db/wal_manager.h"
# include "db/wal_manager.h"
@ -269,10 +270,11 @@ Status CheckpointImpl::CreateCustomCheckpoint(
size_t wal_size = live_wal_files . size ( ) ;
size_t wal_size = live_wal_files . size ( ) ;
// process live files, non-table files first
// process live files, non-table, non-blob files first
std : : string manifest_fname , current_fname ;
std : : string manifest_fname , current_fname ;
// record table files for processing next
// record table and blob files for processing next
std : : vector < std : : pair < std : : string , uint64_t > > live_table_files ;
std : : vector < std : : tuple < std : : string , uint64_t , FileType > >
live_table_and_blob_files ;
for ( auto & live_file : live_files ) {
for ( auto & live_file : live_files ) {
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
break ;
break ;
@ -284,8 +286,8 @@ Status CheckpointImpl::CreateCustomCheckpoint(
s = Status : : Corruption ( " Can't parse file name. This is very bad " ) ;
s = Status : : Corruption ( " Can't parse file name. This is very bad " ) ;
break ;
break ;
}
}
// we should only get sst, options, manifest and current files here
// we should only get sst, blob, options, manifest and current files here
assert ( type = = kTableFile | | type = = kDescriptorFile | |
assert ( type = = kTableFile | | type = = kBlobFile | | type = = k DescriptorFile | |
type = = kCurrentFile | | type = = kOptionsFile ) ;
type = = kCurrentFile | | type = = kOptionsFile ) ;
assert ( live_file . size ( ) > 0 & & live_file [ 0 ] = = ' / ' ) ;
assert ( live_file . size ( ) > 0 & & live_file [ 0 ] = = ' / ' ) ;
if ( type = = kCurrentFile ) {
if ( type = = kCurrentFile ) {
@ -297,15 +299,16 @@ Status CheckpointImpl::CreateCustomCheckpoint(
} else if ( type = = kDescriptorFile ) {
} else if ( type = = kDescriptorFile ) {
manifest_fname = live_file ;
manifest_fname = live_file ;
}
}
if ( type ! = kTableFile ) {
// copy non-table files here
if ( type ! = kTableFile & & type ! = kBlobFile ) {
// copy non-table, non-blob files here
// * if it's kDescriptorFile, limit the size to manifest_file_size
// * if it's kDescriptorFile, limit the size to manifest_file_size
s = copy_file_cb ( db_ - > GetName ( ) , live_file ,
s = copy_file_cb ( db_ - > GetName ( ) , live_file ,
( type = = kDescriptorFile ) ? manifest_file_size : 0 , type ,
( type = = kDescriptorFile ) ? manifest_file_size : 0 , type ,
kUnknownFileChecksumFuncName , kUnknownFileChecksum ) ;
kUnknownFileChecksumFuncName , kUnknownFileChecksum ) ;
} else {
} else {
// process table files below
// process table and blob files below
live_table_files . push_back ( make_pair ( live_file , number ) ) ;
live_table_and_blob_ files . emplace_back ( live_file , number , type ) ;
}
}
}
}
@ -322,19 +325,21 @@ Status CheckpointImpl::CreateCustomCheckpoint(
manifest_file_size , checksum_list . get ( ) ) ;
manifest_file_size , checksum_list . get ( ) ) ;
}
}
// copy/hard link live table files
// copy/hard link live table and blob files
for ( auto & ltf : live_table_files ) {
for ( const auto & file : live_table_and_blob _files ) {
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
break ;
break ;
}
}
std : : string & src_fname = ltf . first ;
uint64_t number = ltf . second ;
const std : : string & src_fname = std : : get < 0 > ( file ) ;
const uint64_t number = std : : get < 1 > ( file ) ;
const FileType type = std : : get < 2 > ( file ) ;
// rules:
// rules:
// * for kTableFile, attempt hard link instead of copy.
// * for kTableFile/kBlobFile , attempt hard link instead of copy.
// * but can't hard link across filesystems.
// * but can't hard link across filesystems.
if ( same_fs ) {
if ( same_fs ) {
s = link_file_cb ( db_ - > GetName ( ) , src_fname , kTableFil e) ;
s = link_file_cb ( db_ - > GetName ( ) , src_fname , typ e) ;
if ( s . IsNotSupported ( ) ) {
if ( s . IsNotSupported ( ) ) {
same_fs = false ;
same_fs = false ;
s = Status : : OK ( ) ;
s = Status : : OK ( ) ;
@ -347,6 +352,7 @@ Status CheckpointImpl::CreateCustomCheckpoint(
// we ignore the checksums either they are not required or we failed to
// we ignore the checksums either they are not required or we failed to
// obtain the checksum lsit for old table files that have no file
// obtain the checksum lsit for old table files that have no file
// checksums
// checksums
// TODO: support this verification for blob files
if ( get_live_table_checksum ) {
if ( get_live_table_checksum ) {
// find checksum info for table files
// find checksum info for table files
Status search = checksum_list - > SearchOneFileChecksum (
Status search = checksum_list - > SearchOneFileChecksum (
@ -359,7 +365,7 @@ Status CheckpointImpl::CreateCustomCheckpoint(
assert ( checksum_value = = kUnknownFileChecksum ) ;
assert ( checksum_value = = kUnknownFileChecksum ) ;
}
}
}
}
s = copy_file_cb ( db_ - > GetName ( ) , src_fname , 0 , kTableFil e, checksum_name ,
s = copy_file_cb ( db_ - > GetName ( ) , src_fname , 0 , typ e, checksum_name ,
checksum_value ) ;
checksum_value ) ;
}
}
}
}