3838import org .junit .After ;
3939import org .junit .Assert ;
4040import org .junit .Before ;
41+ import org .junit .Ignore ;
4142import org .junit .Test ;
4243import org .mockito .Mockito ;
4344
4445import java .io .File ;
4546import java .io .IOException ;
47+ import java .nio .file .FileStore ;
48+ import java .nio .file .Files ;
49+ import java .nio .file .Path ;
4650import java .util .ArrayList ;
4751import java .util .List ;
4852
53+ import static org .apache .iotdb .consensus .iot .IoTConsensusServerImpl .SNAPSHOT_DIR_NAME ;
4954import static org .apache .tsfile .common .constant .TsFileConstant .PATH_SEPARATOR ;
55+ import static org .junit .Assert .assertEquals ;
5056
5157public class IoTDBSnapshotTest {
5258 private String [][] testDataDirs =
@@ -65,11 +71,12 @@ public void tearDown() throws IOException, StorageEngineException {
6571 FileUtils .recursivelyDeleteFolder ("target" + File .separator + "tmp" );
6672 }
6773
68- private List <TsFileResource > writeTsFiles () throws IOException , WriteProcessException {
74+ private List <TsFileResource > writeTsFiles (String [] dataDirs )
75+ throws IOException , WriteProcessException {
6976 List <TsFileResource > resources = new ArrayList <>();
7077 for (int i = 0 ; i < 100 ; i ++) {
7178 String filePath =
72- testDataDirs [ 0 ][ i % 3 ]
79+ dataDirs [ i % dataDirs . length ]
7380 + File .separator
7481 + "sequence"
7582 + File .separator
@@ -108,7 +115,7 @@ public void testCreateSnapshot()
108115 IoTDBDescriptor .getInstance ().getConfig ().setTierDataDirs (testDataDirs );
109116 TierManager .getInstance ().resetFolders ();
110117 try {
111- List <TsFileResource > resources = writeTsFiles ();
118+ List <TsFileResource > resources = writeTsFiles (testDataDirs [ 0 ] );
112119 DataRegion region = new DataRegion (testSgName , "0" );
113120 region .getTsFileManager ().addAll (resources , true );
114121 File snapshotDir = new File ("target" + File .separator + "snapshot" );
@@ -117,12 +124,12 @@ public void testCreateSnapshot()
117124 new SnapshotTaker (region ).takeFullSnapshot (snapshotDir .getAbsolutePath (), true );
118125 File [] files =
119126 snapshotDir .listFiles ((dir , name ) -> name .equals (SnapshotLogger .SNAPSHOT_LOG_NAME ));
120- Assert . assertEquals (1 , files .length );
127+ assertEquals (1 , files .length );
121128 SnapshotLogAnalyzer analyzer = new SnapshotLogAnalyzer (files [0 ]);
122129 Assert .assertTrue (analyzer .isSnapshotComplete ());
123130 int cnt = analyzer .getTotalFileCountInSnapshot ();
124131 analyzer .close ();
125- Assert . assertEquals (200 , cnt );
132+ assertEquals (200 , cnt );
126133 for (TsFileResource resource : resources ) {
127134 Assert .assertTrue (resource .tryWriteLock ());
128135 }
@@ -142,7 +149,7 @@ public void testCreateSnapshotWithUnclosedTsFile()
142149 IoTDBDescriptor .getInstance ().getConfig ().setTierDataDirs (testDataDirs );
143150 TierManager .getInstance ().resetFolders ();
144151 try {
145- List <TsFileResource > resources = writeTsFiles ();
152+ List <TsFileResource > resources = writeTsFiles (testDataDirs [ 0 ] );
146153 resources .subList (50 , 100 ).forEach (x -> x .setStatusForTest (TsFileResourceStatus .UNCLOSED ));
147154 DataRegion region = new DataRegion (testSgName , "0" );
148155 region .setAllowCompaction (false );
@@ -153,13 +160,13 @@ public void testCreateSnapshotWithUnclosedTsFile()
153160 new SnapshotTaker (region ).takeFullSnapshot (snapshotDir .getAbsolutePath (), true );
154161 File [] files =
155162 snapshotDir .listFiles ((dir , name ) -> name .equals (SnapshotLogger .SNAPSHOT_LOG_NAME ));
156- Assert . assertEquals (1 , files .length );
163+ assertEquals (1 , files .length );
157164 SnapshotLogAnalyzer analyzer = new SnapshotLogAnalyzer (files [0 ]);
158165 int cnt = 0 ;
159166 Assert .assertTrue (analyzer .isSnapshotComplete ());
160167 cnt = analyzer .getTotalFileCountInSnapshot ();
161168 analyzer .close ();
162- Assert . assertEquals (100 , cnt );
169+ assertEquals (100 , cnt );
163170 for (TsFileResource resource : resources ) {
164171 Assert .assertTrue (resource .tryWriteLock ());
165172 }
@@ -179,7 +186,7 @@ public void testLoadSnapshot()
179186 IoTDBDescriptor .getInstance ().getConfig ().setTierDataDirs (testDataDirs );
180187 TierManager .getInstance ().resetFolders ();
181188 try {
182- List <TsFileResource > resources = writeTsFiles ();
189+ List <TsFileResource > resources = writeTsFiles (testDataDirs [ 0 ] );
183190 DataRegion region = new DataRegion (testSgName , "0" );
184191 CompressionRatio .getInstance ().updateRatio (100 , 100 , "0" );
185192 region .getTsFileManager ().addAll (resources , true );
@@ -195,8 +202,8 @@ public void testLoadSnapshot()
195202 .loadSnapshotForStateMachine ();
196203 Assert .assertNotNull (dataRegion );
197204 List <TsFileResource > resource = dataRegion .getTsFileManager ().getTsFileList (true );
198- Assert . assertEquals (100 , resource .size ());
199- Assert . assertEquals (
205+ assertEquals (100 , resource .size ());
206+ assertEquals (
200207 new Pair <>(100L , 100L ),
201208 CompressionRatio .getInstance ().getDataRegionRatioMap ().get ("0" ));
202209 } finally {
@@ -208,6 +215,86 @@ public void testLoadSnapshot()
208215 }
209216 }
210217
218+ @ Ignore ("Need manual execution to specify different disks" )
219+ @ Test
220+ public void testLoadSnapshotNoHardLink ()
221+ throws IOException , WriteProcessException , DirectoryNotLegalException {
222+ IoTDBDescriptor .getInstance ().getConfig ().setKeepSameDiskWhenLoadingSnapshot (true );
223+ // initialize dirs
224+ String [][] dataDirsForDB = new String [][] {{"C://snapshot_test" , "D://snapshot_test" }};
225+ File snapshotDir = new File ("D://snapshot_store//" );
226+ if (snapshotDir .exists ()) {
227+ FileUtils .recursivelyDeleteFolder (snapshotDir .getAbsolutePath ());
228+ }
229+ for (String [] dirs : dataDirsForDB ) {
230+ for (String dir : dirs ) {
231+ if (new File (dir ).exists ()) {
232+ FileUtils .recursivelyDeleteFolder (dir );
233+ }
234+ }
235+ }
236+ IoTDBDescriptor .getInstance ().getConfig ().setTierDataDirs (dataDirsForDB );
237+ TierManager .getInstance ().resetFolders ();
238+
239+ // prepare files, files should be written into two folders
240+ List <TsFileResource > resources = writeTsFiles (dataDirsForDB [0 ]);
241+ DataRegion region = new DataRegion (testSgName , "0" );
242+ region .getTsFileManager ().addAll (resources , true );
243+
244+ // take a snapshot into one disk
245+ Assert .assertTrue (snapshotDir .exists () || snapshotDir .mkdirs ());
246+ try {
247+ Assert .assertTrue (
248+ new SnapshotTaker (region ).takeFullSnapshot (snapshotDir .getAbsolutePath (), true ));
249+ File [] files =
250+ snapshotDir .listFiles ((dir , name ) -> name .equals (SnapshotLogger .SNAPSHOT_LOG_NAME ));
251+ // use loadWithoutLog
252+ if (files != null && files .length > 0 ) {
253+ files [0 ].delete ();
254+ }
255+ // move files to snapshot store (simulate snapshot transfer)
256+ for (String dir : dataDirsForDB [0 ]) {
257+ File internalSnapshotDir = new File (dir , SNAPSHOT_DIR_NAME );
258+ if (internalSnapshotDir .exists ()) {
259+ for (File file : FileUtils .listFilesRecursively (internalSnapshotDir , f -> true )) {
260+ if (file .isFile ()) {
261+ String absolutePath = file .getAbsolutePath ();
262+ int snapshotIdIndex = absolutePath .indexOf ("snapshot_store" );
263+ int suffixIndex = snapshotIdIndex + "snapshot_store" .length ();
264+ String suffix = absolutePath .substring (suffixIndex );
265+ File snapshotFile = new File (snapshotDir , suffix );
266+ FileUtils .copyFile (file , snapshotFile );
267+ }
268+ }
269+ }
270+ }
271+
272+ // load the snapshot
273+ DataRegion dataRegion =
274+ new SnapshotLoader (snapshotDir .getAbsolutePath (), testSgName , "0" )
275+ .loadSnapshotForStateMachine ();
276+ Assert .assertNotNull (dataRegion );
277+ resources = dataRegion .getTsFileManager ().getTsFileList (true );
278+ assertEquals (100 , resources .size ());
279+
280+ // files should not be moved to another disk
281+ Path snapshotDirPath = snapshotDir .toPath ();
282+ FileStore snapshotFileStore = Files .getFileStore (snapshotDirPath );
283+ for (TsFileResource tsFileResource : resources ) {
284+ Path tsfilePath = tsFileResource .getTsFile ().toPath ();
285+ FileStore tsFileFileStore = Files .getFileStore (tsfilePath );
286+ assertEquals (snapshotFileStore , tsFileFileStore );
287+ }
288+ } finally {
289+ FileUtils .recursivelyDeleteFolder (snapshotDir .getAbsolutePath ());
290+ for (String [] dirs : dataDirsForDB ) {
291+ for (String dir : dirs ) {
292+ FileUtils .recursivelyDeleteFolder (dir );
293+ }
294+ }
295+ }
296+ }
297+
211298 @ Test
212299 public void testGetSnapshotFile () throws IOException {
213300 File tsFile =
@@ -228,7 +315,7 @@ public void testGetSnapshotFile() throws IOException {
228315 Mockito .when (region .getDataRegionIdString ()).thenReturn ("0" );
229316 File snapshotFile =
230317 new SnapshotTaker (region ).getSnapshotFilePathForTsFile (tsFile , "test-snapshotId" );
231- Assert . assertEquals (
318+ assertEquals (
232319 new File (
233320 IoTDBDescriptor .getInstance ().getConfig ().getLocalDataDirs ()[0 ]
234321 + File .separator
0 commit comments