[ 
https://issues.apache.org/jira/browse/IGNITE-28870?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Oleg Valuyskiy updated IGNITE-28870:
------------------------------------
    Description:     (was: h3. Problem

After a snapshot is successfully created, Ignite may log the following ERROR 
during snapshot temporary directory cleanup:
{code:java}
Snapshot directory doesn't exist [snpName=<snapshot_name>, 
dir=<work_dir>/db/<consistent_id>/snp]{code}
At the same time, the snapshot itself is successfully created in the configured 
snapshot directory.

The error is misleading because it is logged after the snapshot has already 
been successfully created and the temporary snapshot directory has already been 
removed.

Reproducer: [^SnapshotTmpDirCleanupReproducer.patch]
h3. Root cause

Before the changes introduced as part of {*}IGNITE-24130 / PR #11896{*}, 
snapshot cleanup logic 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}
The original logic was:
 * delete the temporary directory of the current snapshot operation: 
*sft.tempFileTree().nodeStorage()*
 * then check the parent temporary snapshot root: *sft.tempFileTree().root()*
 * if the parent temporary root has no other files/directories, delete it as 
well

So the cleanup logic relied on two different filesystem levels:
{code:java}
<work_dir>/db/<consistent_id>/snp
└── <snapshot_name>{code}
Where:
 * nodeStorage() pointed to the temporary directory of the current snapshot
 * root() pointed to the parent temporary root directory that may contain 
temporary directories of other snapshots

After the refactoring, this logic was extracted into a helper method that 
receives 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}
As a result, the same directory is used both as:
 * the directory to delete
 * the directory to inspect with U.fileCount(...);
 * the directory to delete again

This breaks the original two-level cleanup logic. The method first deletes the 
temporary snapshot directory:
{code:java}
U.delete(dir);{code}
Then it tries to count files in the same already deleted directory:
{code:java}
U.fileCount(dir.toPath()){code}
If the directory was successfully removed, U.fileCount(...) throws 
{*}NoSuchFileException{*}, and Ignite logs an ERROR even though cleanup has 
actually succeeded.
h3. Why err should not be used in the new helper

The current snapshot temporary directory is already deleted unconditionally:
{code:java}
U.delete(dir);{code}
Therefore, *err* is not needed to decide whether to remove the current snapshot 
temporary directory.

Using *err* to delete the parent root directory seems to be questionable. The 
error belongs to the current snapshot operation, while the parent temporary 
root may contain other temporary snapshot directories. Therefore, the parent 
root should only be removed when it becomes empty, not because the current 
snapshot operation has failed.
h3. Expected behavior

Snapshot cleanup should:
 * always delete the temporary directory of the current snapshot operation
 * delete the parent temporary snapshot root only if it becomes empty after that
 * not log ERROR if the temporary snapshot directory has already been 
successfully removed
 * not delete the parent temporary root just because the current snapshot 
operation finished with an error)

> False ERROR is logged during snapshot temporary directory cleanup
> -----------------------------------------------------------------
>
>                 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
>
>




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

Reply via email to