@ -2879,6 +2879,10 @@ Status DBImpl::IngestExternalFile(
ColumnFamilyHandle * column_family ,
ColumnFamilyHandle * column_family ,
const std : : vector < std : : string > & external_files ,
const std : : vector < std : : string > & external_files ,
const IngestExternalFileOptions & ingestion_options ) {
const IngestExternalFileOptions & ingestion_options ) {
if ( external_files . empty ( ) ) {
return Status : : InvalidArgument ( " external_files is empty " ) ;
}
Status status ;
Status status ;
auto cfh = reinterpret_cast < ColumnFamilyHandleImpl * > ( column_family ) ;
auto cfh = reinterpret_cast < ColumnFamilyHandleImpl * > ( column_family ) ;
auto cfd = cfh - > cfd ( ) ;
auto cfd = cfh - > cfd ( ) ;
@ -2896,6 +2900,9 @@ Status DBImpl::IngestExternalFile(
immutable_db_options_ , env_options_ ,
immutable_db_options_ , env_options_ ,
& snapshots_ , ingestion_options ) ;
& snapshots_ , ingestion_options ) ;
SuperVersionContext dummy_sv_ctx ( /* create_superversion */ true ) ;
VersionEdit dummy_edit ;
uint64_t next_file_number = 0 ;
std : : list < uint64_t > : : iterator pending_output_elem ;
std : : list < uint64_t > : : iterator pending_output_elem ;
{
{
InstrumentedMutexLock l ( & mutex_ ) ;
InstrumentedMutexLock l ( & mutex_ ) ;
@ -2906,10 +2913,27 @@ Status DBImpl::IngestExternalFile(
// Make sure that bg cleanup wont delete the files that we are ingesting
// Make sure that bg cleanup wont delete the files that we are ingesting
pending_output_elem = CaptureCurrentFileNumberInPendingOutputs ( ) ;
pending_output_elem = CaptureCurrentFileNumberInPendingOutputs ( ) ;
// If crash happen after a hard link established, Recover function may
// reuse the file number that has already assigned to the internal file,
// and this will overwrite the external file. To protect the external
// file, we have to make sure the file number will never being reused.
next_file_number = versions_ - > FetchAddFileNumber ( external_files . size ( ) ) ;
auto cf_options = cfd - > GetLatestMutableCFOptions ( ) ;
status = versions_ - > LogAndApply ( cfd , * cf_options , & dummy_edit , & mutex_ ,
directories_ . GetDbDir ( ) ) ;
if ( status . ok ( ) ) {
InstallSuperVersionAndScheduleWork ( cfd , & dummy_sv_ctx , * cf_options ) ;
}
}
dummy_sv_ctx . Clean ( ) ;
if ( ! status . ok ( ) ) {
return status ;
}
}
SuperVersion * super_version = cfd - > GetReferencedSuperVersion ( & mutex_ ) ;
SuperVersion * super_version = cfd - > GetReferencedSuperVersion ( & mutex_ ) ;
status = ingestion_job . Prepare ( external_files , super_version ) ;
status = ingestion_job . Prepare ( external_files , next_file_number ,
super_version ) ;
CleanupSuperVersion ( super_version ) ;
CleanupSuperVersion ( super_version ) ;
if ( ! status . ok ( ) ) {
if ( ! status . ok ( ) ) {
InstrumentedMutexLock l ( & mutex_ ) ;
InstrumentedMutexLock l ( & mutex_ ) ;