Subversion Repositories SmartDukaan

Rev

Rev 4952 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3971 mandeep.dh 1
/**
2
 * 
3
 */
4
package in.shop2020.util;
5
 
6
import in.shop2020.storage.bdb.StorageManager;
7
 
8
import java.io.File;
9
import java.io.FileFilter;
10
import java.io.FileInputStream;
11
import java.io.FileOutputStream;
12
import java.io.IOException;
13
import java.nio.channels.FileChannel;
14
import java.util.Arrays;
15
import java.util.Date;
16
 
17
import org.apache.commons.logging.Log;
18
import org.apache.commons.logging.LogFactory;
19
 
20
import com.sleepycat.je.Environment;
21
import com.sleepycat.je.util.DbBackup;
22
 
23
/**
24
 * This Runnable takes hot back up of the bdb database files.
25
 * 
26
 * @author mandeep
27
 */
28
public class BDBHotBackupTask implements Runnable {
29
    private static Log          log                    = LogFactory.getLog(BDBHotBackupTask.class);
30
 
31
    /**
32
     * Archival location of backups
33
     */
5061 mandeep.dh 34
    private static final String MASTER_BACKUP_DIR      = "/data/CMS-daily-backup/bdb-backup";
3971 mandeep.dh 35
 
36
    @Override
37
    public void run() {
38
        log.info("Starting backup process");
39
        DbBackup backupHelper = null;
40
 
41
        try {
42
            Environment env = StorageManager.getStorageManager()
43
                    .getEnvironment();
44
 
45
            backupHelper = new DbBackup(env);
46
 
47
            // Start backup, find out what needs to be copied.
48
            backupHelper.startBackup();
49
            String[] filesForBackup = backupHelper.getLogFilesInBackupSet();
50
 
51
            // Copy the files to archival storage.
52
            backupFiles(filesForBackup, env.getHome(), new File(MASTER_BACKUP_DIR + File.separator + new Date().getTime()));
53
        } finally {
54
            // Remember to exit backup mode, or all log files won't be cleaned
55
            // and disk usage will bloat.
56
            backupHelper.endBackup();
57
        }
58
 
59
        deleteOldBackupDirectories();
60
    }
61
 
62
    /**
63
     * Deletes directories older than 4 days
64
     */
65
    private void deleteOldBackupDirectories() {
66
        File[] directoriesToBeDeleted = new File(MASTER_BACKUP_DIR).listFiles(new FileFilter() {
67
 
68
            @Override
69
            public boolean accept(File file) {
4952 mandeep.dh 70
                long ONE_DAYS_IN_MILLISECONDS = 1000 * 60 * 60 * 24 * 1;
71
                if (new Date().getTime() - file.lastModified() > ONE_DAYS_IN_MILLISECONDS) {
3971 mandeep.dh 72
                    return true;
73
                }
74
 
75
                return false;
76
            }
77
        });
78
 
79
        for (File directory : directoriesToBeDeleted) {
80
            log.info("Deleting directory: " + directory.getName());
81
            for (File file : directory.listFiles()) {
82
                file.delete();
83
            }
84
 
85
            directory.delete();
86
        }
87
    }
88
 
89
    /**
90
     * Copies files to back up directory.
91
     *
92
     * @param filesForBackup    Files to be copied
93
     * @param databaseDir       Source directory
94
     * @param backupDir         backup archival directory
95
     */
96
    private void backupFiles(String[] filesForBackup, File databaseDir,
97
            File backupDir) {
98
        // Determine size of backup
99
        long size = 0;
100
        for (String name : filesForBackup) {
101
            size += new File(databaseDir, name).length();
102
        }
103
 
104
        log.info(String.format("Backing up %d files with a total of %.1fMB",
105
                filesForBackup.length, mb(size)));
106
 
107
        // Ensure files are sorted in order, so that if we fail part way
108
        // through, we don't lose stuff
109
        Arrays.sort(filesForBackup);
110
 
111
        // Creating directory if it does not exists
112
        if (!backupDir.exists()) {
113
            backupDir.mkdir();
114
        }
115
 
116
        long total = 0;
117
        for (String name : filesForBackup) {
118
            File source = new File(databaseDir, name);
119
            File dest = new File(backupDir, name);
120
 
121
            log.info(String.format("% 3d%% Copying %s", total * 100 / size,
122
                    name));
123
            try {
124
                copyFile(source, dest);
125
            } catch (IOException e) {
126
                // If the destination file exists, delete it
127
                if (dest.exists()) {
128
                    dest.delete();
129
                }
130
                throw new RuntimeException(
131
                        "Error occured while copying "
132
                                + name
133
                                + ". Deleting to ensure we don't have a corrupt backup.",
134
                        e);
135
            }
136
 
137
            total += source.length();
138
        }
139
    }
140
 
141
    // Fast NIO copy method
142
    private void copyFile(File sourceFile, File destFile) throws IOException {
143
        if (!destFile.exists()) {
144
            destFile.createNewFile();
145
        }
146
 
147
        FileChannel source = null;
148
        FileChannel destination = null;
149
 
150
        try {
151
            source = new FileInputStream(sourceFile).getChannel();
152
            destination = new FileOutputStream(destFile).getChannel();
153
            destination.transferFrom(source, 0, source.size());
154
        } finally {
155
            if (source != null) {
156
                source.close();
157
            }
158
            if (destination != null) {
159
                destination.close();
160
            }
161
        }
162
    }
163
 
164
    private static double mb(long value) {
165
        return ((double) value) / 1048576;
166
    }
167
}