@ -305,16 +305,16 @@ class BackupEngineImpl : public BackupEngine {
// @param contents If non-empty, the file will be created with these contents.
// @param contents If non-empty, the file will be created with these contents.
Status CopyOrCreateFile ( const std : : string & src , const std : : string & dst ,
Status CopyOrCreateFile ( const std : : string & src , const std : : string & dst ,
const std : : string & contents , Env * src_env ,
const std : : string & contents , Env * src_env ,
Env * dst_env , bool sync , RateLimiter * rate_limiter ,
Env * dst_env , const EnvOptions & src_env_options ,
bool sync , RateLimiter * rate_limiter ,
uint64_t * size = nullptr ,
uint64_t * size = nullptr ,
uint32_t * checksum_value = nullptr ,
uint32_t * checksum_value = nullptr ,
uint64_t size_limit = 0 ,
uint64_t size_limit = 0 ,
std : : function < void ( ) > progress_callback = [ ] ( ) { } ) ;
std : : function < void ( ) > progress_callback = [ ] ( ) { } ) ;
Status CalculateChecksum ( const std : : string & src ,
Status CalculateChecksum ( const std : : string & src , Env * src_env ,
Env * src_env ,
const EnvOptions & src_env_options ,
uint64_t size_limit ,
uint64_t size_limit , uint32_t * checksum_value ) ;
uint32_t * checksum_value ) ;
struct CopyOrCreateResult {
struct CopyOrCreateResult {
uint64_t size ;
uint64_t size ;
@ -331,6 +331,7 @@ class BackupEngineImpl : public BackupEngine {
std : : string contents ;
std : : string contents ;
Env * src_env ;
Env * src_env ;
Env * dst_env ;
Env * dst_env ;
EnvOptions src_env_options ;
bool sync ;
bool sync ;
RateLimiter * rate_limiter ;
RateLimiter * rate_limiter ;
uint64_t size_limit ;
uint64_t size_limit ;
@ -338,14 +339,15 @@ class BackupEngineImpl : public BackupEngine {
std : : function < void ( ) > progress_callback ;
std : : function < void ( ) > progress_callback ;
CopyOrCreateWorkItem ( )
CopyOrCreateWorkItem ( )
: src_path ( " " ) ,
: src_path ( " " ) ,
dst_path ( " " ) ,
dst_path ( " " ) ,
contents ( " " ) ,
contents ( " " ) ,
src_env ( nullptr ) ,
src_env ( nullptr ) ,
dst_env ( nullptr ) ,
dst_env ( nullptr ) ,
sync ( false ) ,
src_env_options ( ) ,
rate_limiter ( nullptr ) ,
sync ( false ) ,
size_limit ( 0 ) { }
rate_limiter ( nullptr ) ,
size_limit ( 0 ) { }
CopyOrCreateWorkItem ( const CopyOrCreateWorkItem & ) = delete ;
CopyOrCreateWorkItem ( const CopyOrCreateWorkItem & ) = delete ;
CopyOrCreateWorkItem & operator = ( const CopyOrCreateWorkItem & ) = delete ;
CopyOrCreateWorkItem & operator = ( const CopyOrCreateWorkItem & ) = delete ;
@ -360,6 +362,7 @@ class BackupEngineImpl : public BackupEngine {
contents = std : : move ( o . contents ) ;
contents = std : : move ( o . contents ) ;
src_env = o . src_env ;
src_env = o . src_env ;
dst_env = o . dst_env ;
dst_env = o . dst_env ;
src_env_options = std : : move ( o . src_env_options ) ;
sync = o . sync ;
sync = o . sync ;
rate_limiter = o . rate_limiter ;
rate_limiter = o . rate_limiter ;
size_limit = o . size_limit ;
size_limit = o . size_limit ;
@ -370,14 +373,15 @@ class BackupEngineImpl : public BackupEngine {
CopyOrCreateWorkItem ( std : : string _src_path , std : : string _dst_path ,
CopyOrCreateWorkItem ( std : : string _src_path , std : : string _dst_path ,
std : : string _contents , Env * _src_env , Env * _dst_env ,
std : : string _contents , Env * _src_env , Env * _dst_env ,
bool _sync , RateLimiter * _rate_limiter ,
EnvOptions _src_env_options , bool _sync ,
uint64_t _size_limit ,
RateLimiter * _rate_limiter , uint64_t _size_limit ,
std : : function < void ( ) > _progress_callback = [ ] ( ) { } )
std : : function < void ( ) > _progress_callback = [ ] ( ) { } )
: src_path ( std : : move ( _src_path ) ) ,
: src_path ( std : : move ( _src_path ) ) ,
dst_path ( std : : move ( _dst_path ) ) ,
dst_path ( std : : move ( _dst_path ) ) ,
contents ( std : : move ( _contents ) ) ,
contents ( std : : move ( _contents ) ) ,
src_env ( _src_env ) ,
src_env ( _src_env ) ,
dst_env ( _dst_env ) ,
dst_env ( _dst_env ) ,
src_env_options ( std : : move ( _src_env_options ) ) ,
sync ( _sync ) ,
sync ( _sync ) ,
rate_limiter ( _rate_limiter ) ,
rate_limiter ( _rate_limiter ) ,
size_limit ( _size_limit ) ,
size_limit ( _size_limit ) ,
@ -471,7 +475,8 @@ class BackupEngineImpl : public BackupEngine {
std : : vector < BackupAfterCopyOrCreateWorkItem > & backup_items_to_finish ,
std : : vector < BackupAfterCopyOrCreateWorkItem > & backup_items_to_finish ,
BackupID backup_id , bool shared , const std : : string & src_dir ,
BackupID backup_id , bool shared , const std : : string & src_dir ,
const std : : string & fname , // starts with "/"
const std : : string & fname , // starts with "/"
RateLimiter * rate_limiter , uint64_t size_bytes , uint64_t size_limit = 0 ,
const EnvOptions & src_env_options , RateLimiter * rate_limiter ,
uint64_t size_bytes , uint64_t size_limit = 0 ,
bool shared_checksum = false ,
bool shared_checksum = false ,
std : : function < void ( ) > progress_callback = [ ] ( ) { } ,
std : : function < void ( ) > progress_callback = [ ] ( ) { } ,
const std : : string & contents = std : : string ( ) ) ;
const std : : string & contents = std : : string ( ) ) ;
@ -723,9 +728,10 @@ Status BackupEngineImpl::Initialize() {
CopyOrCreateResult result ;
CopyOrCreateResult result ;
result . status = CopyOrCreateFile (
result . status = CopyOrCreateFile (
work_item . src_path , work_item . dst_path , work_item . contents ,
work_item . src_path , work_item . dst_path , work_item . contents ,
work_item . src_env , work_item . dst_env , work_item . sync ,
work_item . src_env , work_item . dst_env , work_item . src_env_options ,
work_item . rate_limiter , & result . size , & result . checksum_value ,
work_item . sync , work_item . rate_limiter , & result . size ,
work_item . size_limit , work_item . progress_callback ) ;
& result . checksum_value , work_item . size_limit ,
work_item . progress_callback ) ;
work_item . result . set_value ( std : : move ( result ) ) ;
work_item . result . set_value ( std : : move ( result ) ) ;
}
}
} ) ;
} ) ;
@ -796,8 +802,10 @@ Status BackupEngineImpl::CreateNewBackupWithMetadata(
if ( s . ok ( ) ) {
if ( s . ok ( ) ) {
CheckpointImpl checkpoint ( db ) ;
CheckpointImpl checkpoint ( db ) ;
uint64_t sequence_number = 0 ;
uint64_t sequence_number = 0 ;
DBOptions db_options = db - > GetDBOptions ( ) ;
EnvOptions src_raw_env_options ( db_options ) ;
s = checkpoint . CreateCustomCheckpoint (
s = checkpoint . CreateCustomCheckpoint (
db - > GetDBOptions ( ) ,
db_options ,
[ & ] ( const std : : string & /*src_dirname*/ , const std : : string & /*fname*/ ,
[ & ] ( const std : : string & /*src_dirname*/ , const std : : string & /*fname*/ ,
FileType ) {
FileType ) {
// custom checkpoint will switch to calling copy_file_cb after it sees
// custom checkpoint will switch to calling copy_file_cb after it sees
@ -815,11 +823,33 @@ Status BackupEngineImpl::CreateNewBackupWithMetadata(
if ( type = = kTableFile ) {
if ( type = = kTableFile ) {
st = db_env_ - > GetFileSize ( src_dirname + fname , & size_bytes ) ;
st = db_env_ - > GetFileSize ( src_dirname + fname , & size_bytes ) ;
}
}
EnvOptions src_env_options ;
switch ( type ) {
case kLogFile :
src_env_options =
db_env_ - > OptimizeForLogRead ( src_raw_env_options ) ;
break ;
case kTableFile :
src_env_options = db_env_ - > OptimizeForCompactionTableRead (
src_raw_env_options , ImmutableDBOptions ( db_options ) ) ;
break ;
case kDescriptorFile :
src_env_options =
db_env_ - > OptimizeForManifestRead ( src_raw_env_options ) ;
break ;
default :
// Other backed up files (like options file) are not read by live
// DB, so don't need to worry about avoiding mixing buffered and
// direct I/O. Just use plain defaults.
src_env_options = src_raw_env_options ;
break ;
}
if ( st . ok ( ) ) {
if ( st . ok ( ) ) {
st = AddBackupFileWorkItem (
st = AddBackupFileWorkItem (
live_dst_paths , backup_items_to_finish , new_backup_id ,
live_dst_paths , backup_items_to_finish , new_backup_id ,
options_ . share_table_files & & type = = kTableFile , src_dirname ,
options_ . share_table_files & & type = = kTableFile , src_dirname ,
fname , rate_limiter , size_bytes , size_limit_bytes ,
fname , src_env_options , rate_limiter , size_bytes ,
size_limit_bytes ,
options_ . share_files_with_checksum & & type = = kTableFile ,
options_ . share_files_with_checksum & & type = = kTableFile ,
progress_callback ) ;
progress_callback ) ;
}
}
@ -829,8 +859,9 @@ Status BackupEngineImpl::CreateNewBackupWithMetadata(
Log ( options_ . info_log , " add file for backup %s " , fname . c_str ( ) ) ;
Log ( options_ . info_log , " add file for backup %s " , fname . c_str ( ) ) ;
return AddBackupFileWorkItem (
return AddBackupFileWorkItem (
live_dst_paths , backup_items_to_finish , new_backup_id ,
live_dst_paths , backup_items_to_finish , new_backup_id ,
false /* shared */ , " " /* src_dir */ , fname , rate_limiter ,
false /* shared */ , " " /* src_dir */ , fname ,
contents . size ( ) , 0 /* size_limit */ , false /* shared_checksum */ ,
EnvOptions ( ) /* src_env_options */ , rate_limiter , contents . size ( ) ,
0 /* size_limit */ , false /* shared_checksum */ ,
progress_callback , contents ) ;
progress_callback , contents ) ;
} /* create_file_cb */ ,
} /* create_file_cb */ ,
& sequence_number , flush_before_backup ? 0 : port : : kMaxUint64 ) ;
& sequence_number , flush_before_backup ? 0 : port : : kMaxUint64 ) ;
@ -1114,7 +1145,8 @@ Status BackupEngineImpl::RestoreDBFromBackup(
dst . c_str ( ) ) ;
dst . c_str ( ) ) ;
CopyOrCreateWorkItem copy_or_create_work_item (
CopyOrCreateWorkItem copy_or_create_work_item (
GetAbsolutePath ( file ) , dst , " " /* contents */ , backup_env_ , db_env_ ,
GetAbsolutePath ( file ) , dst , " " /* contents */ , backup_env_ , db_env_ ,
false , rate_limiter , 0 /* size_limit */ ) ;
EnvOptions ( ) /* src_env_options */ , false , rate_limiter ,
0 /* size_limit */ ) ;
RestoreAfterCopyOrCreateWorkItem after_copy_or_create_work_item (
RestoreAfterCopyOrCreateWorkItem after_copy_or_create_work_item (
copy_or_create_work_item . result . get_future ( ) ,
copy_or_create_work_item . result . get_future ( ) ,
file_info - > checksum_value ) ;
file_info - > checksum_value ) ;
@ -1183,15 +1215,15 @@ Status BackupEngineImpl::VerifyBackup(BackupID backup_id) {
Status BackupEngineImpl : : CopyOrCreateFile (
Status BackupEngineImpl : : CopyOrCreateFile (
const std : : string & src , const std : : string & dst , const std : : string & contents ,
const std : : string & src , const std : : string & dst , const std : : string & contents ,
Env * src_env , Env * dst_env , bool sync , RateLimiter * rate_limiter ,
Env * src_env , Env * dst_env , const EnvOptions & src_env_options , bool sync ,
uint64_t * size , uint32_t * checksum_value , uint64_t size_limit ,
RateLimiter * rate_limiter , uint64_t * size , uint32_t * checksum_value ,
std : : function < void ( ) > progress_callback ) {
uint64_t size_limit , std : : function < void ( ) > progress_callback ) {
assert ( src . empty ( ) ! = contents . empty ( ) ) ;
assert ( src . empty ( ) ! = contents . empty ( ) ) ;
Status s ;
Status s ;
std : : unique_ptr < WritableFile > dst_file ;
std : : unique_ptr < WritableFile > dst_file ;
std : : unique_ptr < SequentialFile > src_file ;
std : : unique_ptr < SequentialFile > src_file ;
EnvOptions env_options ;
EnvOptions dst_ env_options;
env_options . use_mmap_writes = false ;
dst_ env_options. use_mmap_writes = false ;
// TODO:(gzh) maybe use direct reads/writes here if possible
// TODO:(gzh) maybe use direct reads/writes here if possible
if ( size ! = nullptr ) {
if ( size ! = nullptr ) {
* size = 0 ;
* size = 0 ;
@ -1205,16 +1237,16 @@ Status BackupEngineImpl::CopyOrCreateFile(
size_limit = std : : numeric_limits < uint64_t > : : max ( ) ;
size_limit = std : : numeric_limits < uint64_t > : : max ( ) ;
}
}
s = dst_env - > NewWritableFile ( dst , & dst_file , env_options ) ;
s = dst_env - > NewWritableFile ( dst , & dst_file , dst_ env_options) ;
if ( s . ok ( ) & & ! src . empty ( ) ) {
if ( s . ok ( ) & & ! src . empty ( ) ) {
s = src_env - > NewSequentialFile ( src , & src_file , env_options ) ;
s = src_env - > NewSequentialFile ( src , & src_file , src_ env_options) ;
}
}
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
return s ;
return s ;
}
}
std : : unique_ptr < WritableFileWriter > dest_writer (
std : : unique_ptr < WritableFileWriter > dest_writer (
new WritableFileWriter ( std : : move ( dst_file ) , dst , env_options ) ) ;
new WritableFileWriter ( std : : move ( dst_file ) , dst , dst_ env_options) ) ;
std : : unique_ptr < SequentialFileReader > src_reader ;
std : : unique_ptr < SequentialFileReader > src_reader ;
std : : unique_ptr < char [ ] > buf ;
std : : unique_ptr < char [ ] > buf ;
if ( ! src . empty ( ) ) {
if ( ! src . empty ( ) ) {
@ -1276,9 +1308,10 @@ Status BackupEngineImpl::AddBackupFileWorkItem(
std : : unordered_set < std : : string > & live_dst_paths ,
std : : unordered_set < std : : string > & live_dst_paths ,
std : : vector < BackupAfterCopyOrCreateWorkItem > & backup_items_to_finish ,
std : : vector < BackupAfterCopyOrCreateWorkItem > & backup_items_to_finish ,
BackupID backup_id , bool shared , const std : : string & src_dir ,
BackupID backup_id , bool shared , const std : : string & src_dir ,
const std : : string & fname , RateLimiter * rate_limiter , uint64_t size_bytes ,
const std : : string & fname , const EnvOptions & src_env_options ,
uint64_t size_limit , bool shared_checksum ,
RateLimiter * rate_limiter , uint64_t size_bytes , uint64_t size_limit ,
std : : function < void ( ) > progress_callback , const std : : string & contents ) {
bool shared_checksum , std : : function < void ( ) > progress_callback ,
const std : : string & contents ) {
assert ( ! fname . empty ( ) & & fname [ 0 ] = = ' / ' ) ;
assert ( ! fname . empty ( ) & & fname [ 0 ] = = ' / ' ) ;
assert ( contents . empty ( ) ! = src_dir . empty ( ) ) ;
assert ( contents . empty ( ) ! = src_dir . empty ( ) ) ;
@ -1289,7 +1322,7 @@ Status BackupEngineImpl::AddBackupFileWorkItem(
if ( shared & & shared_checksum ) {
if ( shared & & shared_checksum ) {
// add checksum and file length to the file name
// add checksum and file length to the file name
s = CalculateChecksum ( src_dir + fname , db_env_ , size_limit ,
s = CalculateChecksum ( src_dir + fname , db_env_ , src_env_options , s ize_limit ,
& checksum_value ) ;
& checksum_value ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
return s ;
return s ;
@ -1365,8 +1398,8 @@ Status BackupEngineImpl::AddBackupFileWorkItem(
// the file is present and referenced by a backup
// the file is present and referenced by a backup
ROCKS_LOG_INFO ( options_ . info_log ,
ROCKS_LOG_INFO ( options_ . info_log ,
" %s already present, calculate checksum " , fname . c_str ( ) ) ;
" %s already present, calculate checksum " , fname . c_str ( ) ) ;
s = CalculateChecksum ( src_dir + fname , db_env_ , size_limit ,
s = CalculateChecksum ( src_dir + fname , db_env_ , src_env_options ,
& checksum_value ) ;
size_limit , & checksum_value ) ;
}
}
}
}
live_dst_paths . insert ( final_dest_path ) ;
live_dst_paths . insert ( final_dest_path ) ;
@ -1376,8 +1409,8 @@ Status BackupEngineImpl::AddBackupFileWorkItem(
copy_dest_path - > c_str ( ) ) ;
copy_dest_path - > c_str ( ) ) ;
CopyOrCreateWorkItem copy_or_create_work_item (
CopyOrCreateWorkItem copy_or_create_work_item (
src_dir . empty ( ) ? " " : src_dir + fname , * copy_dest_path , contents ,
src_dir . empty ( ) ? " " : src_dir + fname , * copy_dest_path , contents ,
db_env_ , backup_env_ , options_ . sync , rate_limiter , size_limit ,
db_env_ , backup_env_ , src_env_options , options_ . sync , rate_limiter ,
progress_callback ) ;
size_limit , progress_callback ) ;
BackupAfterCopyOrCreateWorkItem after_copy_or_create_work_item (
BackupAfterCopyOrCreateWorkItem after_copy_or_create_work_item (
copy_or_create_work_item . result . get_future ( ) , shared , need_to_copy ,
copy_or_create_work_item . result . get_future ( ) , shared , need_to_copy ,
backup_env_ , temp_dest_path , final_dest_path , dst_relative ) ;
backup_env_ , temp_dest_path , final_dest_path , dst_relative ) ;
@ -1399,6 +1432,7 @@ Status BackupEngineImpl::AddBackupFileWorkItem(
}
}
Status BackupEngineImpl : : CalculateChecksum ( const std : : string & src , Env * src_env ,
Status BackupEngineImpl : : CalculateChecksum ( const std : : string & src , Env * src_env ,
const EnvOptions & src_env_options ,
uint64_t size_limit ,
uint64_t size_limit ,
uint32_t * checksum_value ) {
uint32_t * checksum_value ) {
* checksum_value = 0 ;
* checksum_value = 0 ;
@ -1406,12 +1440,8 @@ Status BackupEngineImpl::CalculateChecksum(const std::string& src, Env* src_env,
size_limit = std : : numeric_limits < uint64_t > : : max ( ) ;
size_limit = std : : numeric_limits < uint64_t > : : max ( ) ;
}
}
EnvOptions env_options ;
env_options . use_mmap_writes = false ;
env_options . use_direct_reads = false ;
std : : unique_ptr < SequentialFile > src_file ;
std : : unique_ptr < SequentialFile > src_file ;
Status s = src_env - > NewSequentialFile ( src , & src_file , env_options ) ;
Status s = src_env - > NewSequentialFile ( src , & src_file , src_env_options ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
return s ;
return s ;
}
}