You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							85 lines
						
					
					
						
							2.5 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							85 lines
						
					
					
						
							2.5 KiB
						
					
					
				
								package weed_server
							 | 
						|
								
							 | 
						|
								import (
							 | 
						|
									"fmt"
							 | 
						|
									"time"
							 | 
						|
								
							 | 
						|
									"github.com/seaweedfs/seaweedfs/weed/pb/volume_server_pb"
							 | 
						|
									"github.com/seaweedfs/seaweedfs/weed/storage/backend"
							 | 
						|
									"github.com/seaweedfs/seaweedfs/weed/storage/needle"
							 | 
						|
								)
							 | 
						|
								
							 | 
						|
								// VolumeTierMoveDatFromRemote copy dat file from a remote tier to local volume server
							 | 
						|
								func (vs *VolumeServer) VolumeTierMoveDatFromRemote(req *volume_server_pb.VolumeTierMoveDatFromRemoteRequest, stream volume_server_pb.VolumeServer_VolumeTierMoveDatFromRemoteServer) error {
							 | 
						|
								
							 | 
						|
									// find existing volume
							 | 
						|
									v := vs.store.GetVolume(needle.VolumeId(req.VolumeId))
							 | 
						|
									if v == nil {
							 | 
						|
										return fmt.Errorf("volume %d not found", req.VolumeId)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									// verify the collection
							 | 
						|
									if v.Collection != req.Collection {
							 | 
						|
										return fmt.Errorf("existing collection:%v unexpected input: %v", v.Collection, req.Collection)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									// locate the disk file
							 | 
						|
									storageName, storageKey := v.RemoteStorageNameKey()
							 | 
						|
									if storageName == "" || storageKey == "" {
							 | 
						|
										return fmt.Errorf("volume %d is already on local disk", req.VolumeId)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									// check whether the local .dat already exists
							 | 
						|
									_, ok := v.DataBackend.(*backend.DiskFile)
							 | 
						|
									if ok {
							 | 
						|
										return fmt.Errorf("volume %d is already on local disk", req.VolumeId)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									// check valid storage backend type
							 | 
						|
									backendStorage, found := backend.BackendStorages[storageName]
							 | 
						|
									if !found {
							 | 
						|
										var keys []string
							 | 
						|
										for key := range backend.BackendStorages {
							 | 
						|
											keys = append(keys, key)
							 | 
						|
										}
							 | 
						|
										return fmt.Errorf("remote storage %s not found from supported: %v", storageName, keys)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									startTime := time.Now()
							 | 
						|
									fn := func(progressed int64, percentage float32) error {
							 | 
						|
										now := time.Now()
							 | 
						|
										if now.Sub(startTime) < time.Second {
							 | 
						|
											return nil
							 | 
						|
										}
							 | 
						|
										startTime = now
							 | 
						|
										return stream.Send(&volume_server_pb.VolumeTierMoveDatFromRemoteResponse{
							 | 
						|
											Processed:           progressed,
							 | 
						|
											ProcessedPercentage: percentage,
							 | 
						|
										})
							 | 
						|
									}
							 | 
						|
									// copy the data file
							 | 
						|
									_, err := backendStorage.DownloadFile(v.FileName(".dat"), storageKey, fn)
							 | 
						|
									if err != nil {
							 | 
						|
										return fmt.Errorf("backend %s copy file %s: %v", storageName, v.FileName(".dat"), err)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									if req.KeepRemoteDatFile {
							 | 
						|
										return nil
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									// remove remote file
							 | 
						|
									if err := backendStorage.DeleteFile(storageKey); err != nil {
							 | 
						|
										return fmt.Errorf("volume %d failed to delete remote file %s: %v", v.Id, storageKey, err)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									// forget remote file
							 | 
						|
									v.GetVolumeInfo().Files = v.GetVolumeInfo().Files[1:]
							 | 
						|
									if err := v.SaveVolumeInfo(); err != nil {
							 | 
						|
										return fmt.Errorf("volume %d failed to save remote file info: %v", v.Id, err)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									v.DataBackend.Close()
							 | 
						|
									v.DataBackend = nil
							 | 
						|
								
							 | 
						|
									return nil
							 | 
						|
								}
							 |