[ 
https://issues.apache.org/jira/browse/IGNITE-28870?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18095669#comment-18095669
 ] 

Ignite TC Bot commented on IGNITE-28870:
----------------------------------------

{panel:title=Branch: [pull/13358/head] Base: [master] : No blockers 
found!|borderStyle=dashed|borderColor=#ccc|titleBGColor=#D6F7C1}{panel}
{panel:title=Branch: [pull/13358/head] Base: [master] : New Tests 
(8)|borderStyle=dashed|borderColor=#ccc|titleBGColor=#D6F7C1}
{color:#00008b}Snapshots 7{color} [[tests 
8|https://ci2.ignite.apache.org/viewLog.html?buildId=9201595]]
* {color:#013220}IgniteSnapshotTestSuite7: 
IgniteSnapshotManagerSelfTest.testSnapshotTmpRootIsRemovedIfNotEmptyOnError[encryption=false,
 onlyPrimay=true] - PASSED{color}
* {color:#013220}IgniteSnapshotTestSuite7: 
IgniteSnapshotManagerSelfTest.testSnapshotTmpRootIsNotRemovedIfNotEmptyOnSuccess[encryption=false,
 onlyPrimay=true] - PASSED{color}
* {color:#013220}IgniteSnapshotTestSuite7: 
IgniteSnapshotManagerSelfTest.testSnapshotTmpRootIsRemovedIfNotEmptyOnError[encryption=false,
 onlyPrimay=false] - PASSED{color}
* {color:#013220}IgniteSnapshotTestSuite7: 
IgniteSnapshotManagerSelfTest.testSnapshotTmpRootIsNotRemovedIfNotEmptyOnSuccess[encryption=false,
 onlyPrimay=false] - PASSED{color}
* {color:#013220}IgniteSnapshotTestSuite7: 
IgniteSnapshotManagerSelfTest.testSnapshotTmpRootIsRemovedIfNotEmptyOnError[encryption=true,
 onlyPrimay=true] - PASSED{color}
* {color:#013220}IgniteSnapshotTestSuite7: 
IgniteSnapshotManagerSelfTest.testSnapshotTmpRootIsNotRemovedIfNotEmptyOnSuccess[encryption=true,
 onlyPrimay=true] - PASSED{color}
* {color:#013220}IgniteSnapshotTestSuite7: 
IgniteSnapshotManagerSelfTest.testSnapshotTmpRootIsRemovedIfNotEmptyOnError[encryption=true,
 onlyPrimay=false] - PASSED{color}
* {color:#013220}IgniteSnapshotTestSuite7: 
IgniteSnapshotManagerSelfTest.testSnapshotTmpRootIsNotRemovedIfNotEmptyOnSuccess[encryption=true,
 onlyPrimay=false] - PASSED{color}

{panel}
[TeamCity *--> Run :: All* 
Results|https://ci2.ignite.apache.org/viewLog.html?buildId=9201603&buildTypeId=IgniteTests24Java8_RunAll]
{color:#ffffff}tcbot-analysis-comment chainBuildId=9201603 
rerunBuildIds=9202192{color}

> Restore snapshot temporary files cleanup logic
> ----------------------------------------------
>
>                 Key: IGNITE-28870
>                 URL: https://issues.apache.org/jira/browse/IGNITE-28870
>             Project: Ignite
>          Issue Type: Bug
>            Reporter: Oleg Valuyskiy
>            Assignee: Oleg Valuyskiy
>            Priority: Minor
>              Labels: ise
>         Attachments: SnapshotTmpDirCleanupReproducer.patch
>
>          Time Spent: 50m
>  Remaining Estimate: 0h
>
> h3. Problem
> After the changes introduced in IGNITE-24130 / PR #11896, the temporary 
> snapshot files cleanup logic was accidentally changed. Previously, snapshot 
> cleanup used two different directories:
> {code:java}
> U.delete(sft.tempFileTree().nodeStorage());
> // Delete snapshot directory if no other files exists.
> try {
>     if (U.fileCount(sft.tempFileTree().root().toPath()) == 0 || err != null)
>         U.delete(sft.tempFileTree().root().toPath());
> }
> catch (IOException e) {
>     log.error("Snapshot directory doesn't exist [snpName=" + snpName + ", 
> dir=" + sft.tempFileTree().root() + ']');
> }
> {code}
> These two directories represent different levels of the temporary snapshot 
> file tree. For example:
>  * sft.tempFileTree().root() - 
> <work_dir>/db/<node_storage>/snp/<snapshot_name>
>  * sft.tempFileTree().nodeStorage() - 
> <work_dir>/db/<node_storage>/snp/<snapshot_name>/db/<node_storage>
> So the original cleanup logic was:
>  * remove the node-specific temporary snapshot storage directory
>  * then check the temporary root directory of the current snapshot
>  * remove the root directory only if it becomes empty
>  * remove the root directory regardless of its contents if snapshot 
> processing finished with an error, because the temporary state of the current 
> snapshot is considered invalid
> In other words, the original logic intentionally worked with two different 
> filesystem levels.
> h3. Regression
> After IGNITE-24130 / PR #11896, the cleanup logic was refactored into a 
> helper method:
> {code:java}
> public static void removeTmpSnapshotFiles(SnapshotFileTree sft, boolean err, 
> IgniteLogger log) {
>     NodeFileTree tmpFt = sft.tempFileTree();
>     ```
>     removeTmpDir(tmpFt.root(), err, log);
>     for (File tmpDrStorage : tmpFt.extraStorages().values())
>         removeTmpDir(tmpDrStorage.getParentFile(), err, log);
>     ```
> }
> {code}
> And the helper currently accepts only one directory:
> {code:java}
> private static void removeTmpDir(File dir, boolean err, IgniteLogger log) {
>     U.delete(dir);
>     ```
>     // Delete snapshot directory if no other files exists.
>     try {
>         if (U.fileCount(dir.toPath()) == 0 || err)
>             U.delete(dir.toPath());
>     }
>     catch (IOException e) {
>         log.error("Snapshot directory doesn't exist [snpName=" + 
> dir.getName() + ", dir=" + dir.getParentFile() + ']');
>     }
>     ```
> }
> {code}
> This accidentally collapses the original two-level cleanup logic into a 
> single directory. As a result, the code now:
>  * removes the snapshot temporary root directory
>  * then tries to count files in the same directory
>  * then tries to delete the same directory again
> For example, instead of deleting:
> {code:java}
> <work_dir>/db/<node_storage>/snp/<snapshot_name>/db/<node_storage>{code}
> and then checking:
> {code:java}
> <work_dir>/db/<node_storage>/snp/<snapshot_name>{code}
> the current implementation deletes:
> {code:java}
> <work_dir>/db/<node_storage>/snp/<snapshot_name>{code}
> and then calls *U.fileCount(...)* for the same already deleted path. This 
> leads to a  false ERROR in the log after a successful snapshot creation:
> {code:java}
> Snapshot directory doesn't exist [snpName=<snapshot_name>, 
> dir=<work_dir>/db/<node_storage>/snp]{code}
> (this is how the issue was identified in the first place, reproducer: 
> [^SnapshotTmpDirCleanupReproducer.patch])
> Thus, because of the cahnges introduced in IGNITE-24130 the original cleanup 
> logic was changed. The success path became more aggressive: the whole 
> snapshot temporary root is removed before checking whether it still contains 
> any unexpected files. Previously, such a non-empty root was not removed on 
> the success path.
> h3. Expected behavior
> The cleanup logic should restore the original two-level behavior:
>  * remove the node-specific temporary snapshot storage directory
>  * then check the snapshot temporary root directory
>  * remove the root directory if it becomes empty
>  * remove the root directory regardless of its contents if snapshot 
> processing finished with an error
>  * do not call *U.fileCount(...)* on the directory that has just been deleted
>  * do not log an error when the temporary directory has already been 
> successfully removed



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to