@Override public boolean apply(BackupInfo info) { if (setName == null) { return true; } String backupId = info.getBackupId(); return backupId.startsWith(setName); } };
/** * We use only time stamps to compare objects during sort operation */ @Override public int compareTo(BackupInfo o) { Long thisTS = Long.valueOf(this.getBackupId().substring(this.getBackupId().lastIndexOf("_") + 1)); Long otherTS = Long.valueOf(o.getBackupId().substring(o.getBackupId().lastIndexOf("_") + 1)); return thisTS.compareTo(otherTS); } }
private String[] convertToBackupIds(List<BackupInfo> history) { String[] ids = new String[history.size()]; for (int i = 0; i < ids.length; i++) { ids[i] = history.get(i).getBackupId(); } return ids; }
@Override public int compare(BackupInfo o1, BackupInfo o2) { long ts1 = getTimestamp(o1.getBackupId()); long ts2 = getTimestamp(o2.getBackupId()); if (ts1 == ts2) { return 0; } return ts1 < ts2 ? 1 : -1; }
protected Path getBulkOutputDir() { String backupId = backupInfo.getBackupId(); Path path = new Path(backupInfo.getBackupRootDir()); path = new Path(path, ".tmp"); path = new Path(path, backupId); return path; } }
/** * Check if any ongoing backup. Currently, we only reply on checking status in backup system * table. We need to consider to handle the case of orphan records in the future. Otherwise, all * the coming request will fail. * @return the ongoing backup id if on going backup exists, otherwise null * @throws IOException exception */ private String getOngoingBackupId() throws IOException { ArrayList<BackupInfo> sessions = systemTable.getBackupInfos(BackupState.RUNNING); if (sessions.size() == 0) { return null; } return sessions.get(0).getBackupId(); }
public String getStatusAndProgressAsString() { StringBuilder sb = new StringBuilder(); sb.append("id: ").append(getBackupId()).append(" state: ").append(getState()) .append(" progress: ").append(getProgress()); return sb.toString(); }
/** * Update the ongoing backup with new progress. * @param backupInfo backup info * @param newProgress progress * @param bytesCopied bytes copied * @throws NoNodeException exception */ static void updateProgress(BackupInfo backupInfo, BackupManager backupManager, int newProgress, long bytesCopied) throws IOException { // compose the new backup progress data, using fake number for now String backupProgressData = newProgress + "%"; backupInfo.setProgress(newProgress); backupManager.updateBackupInfo(backupInfo); LOG.debug("Backup progress data \"" + backupProgressData + "\" has been updated to backup system table for " + backupInfo.getBackupId()); }
/** * Creates Put operation for a given backup info object * @param context backup info * @return put operation * @throws IOException exception */ private Put createPutForBackupInfo(BackupInfo context) throws IOException { Put put = new Put(rowkey(BACKUP_INFO_PREFIX, context.getBackupId())); put.addColumn(BackupSystemTable.SESSIONS_FAMILY, Bytes.toBytes("context"), context.toByteArray()); return put; }
/** * Saves list of WAL files after incremental backup operation. These files will be stored until * TTL expiration and are used by Backup Log Cleaner plug-in to determine which WAL files can be * safely purged. */ public void recordWALFiles(List<String> files) throws IOException { systemTable.addWALFiles(files, backupInfo.getBackupId(), backupInfo.getBackupRootDir()); }
/** * Delete HBase snapshot for backup. * @param backupInfo backup info * @throws IOException exception */ protected static void deleteSnapshots(final Connection conn, BackupInfo backupInfo, Configuration conf) throws IOException { LOG.debug("Trying to delete snapshot for full backup."); for (String snapshotName : backupInfo.getSnapshotNames()) { if (snapshotName == null) { continue; } LOG.debug("Trying to delete snapshot: " + snapshotName); try (Admin admin = conn.getAdmin()) { admin.deleteSnapshot(snapshotName); } LOG.debug("Deleting the snapshot " + snapshotName + " for backup " + backupInfo.getBackupId() + " succeeded."); } }
/** * Updates status (state) of a backup session in backup system table table * @param info backup info * @throws IOException exception */ public void updateBackupInfo(BackupInfo info) throws IOException { if (LOG.isTraceEnabled()) { LOG.trace("update backup status in backup system table for: " + info.getBackupId() + " set status=" + info.getState()); } try (Table table = connection.getTable(tableName)) { Put put = createPutForBackupInfo(info); table.put(put); } }
private void removeTableFromBackupImage(BackupInfo info, TableName tn, BackupSystemTable sysTable) throws IOException { List<TableName> tables = info.getTableNames(); LOG.debug("Remove " + tn + " from " + info.getBackupId() + " tables=" + info.getTableListAsString()); if (tables.contains(tn)) { tables.remove(tn); if (tables.isEmpty()) { LOG.debug("Delete backup info " + info.getBackupId()); sysTable.deleteBackupInfo(info.getBackupId()); // Idempotent operation BackupUtils.cleanupBackupData(info, conn.getConfiguration()); } else { info.setTables(tables); sysTable.updateBackupInfo(info); // Now, clean up directory for table (idempotent) cleanupBackupDir(info, tn, conn.getConfiguration()); } } }
private boolean findBackup(List<BackupInfo> history, String backupId) { assertTrue(history.size() > 0); boolean success = false; for (BackupInfo info : history) { if (info.getBackupId().equals(backupId)) { success = true; break; } } return success; }
/** * Begin the overall backup. * @param backupInfo backup info * @throws IOException exception */ protected void beginBackup(BackupManager backupManager, BackupInfo backupInfo) throws IOException { BackupSystemTable.snapshot(conn); backupManager.setBackupInfo(backupInfo); // set the start timestamp of the overall backup long startTs = EnvironmentEdgeManager.currentTime(); backupInfo.setStartTs(startTs); // set overall backup status: ongoing backupInfo.setState(BackupState.RUNNING); backupInfo.setPhase(BackupPhase.REQUEST); LOG.info("Backup " + backupInfo.getBackupId() + " started at " + startTs + "."); backupManager.updateBackupInfo(backupInfo); if (LOG.isDebugEnabled()) { LOG.debug("Backup session " + backupInfo.getBackupId() + " has been started."); } }
/** * Construct a table level manifest for a backup of the named table. * @param backup The ongoing backup session info */ public BackupManifest(BackupInfo backup, TableName table) { this.tableBackupDir = backup.getTableBackupDir(table); List<TableName> tables = new ArrayList<TableName>(); tables.add(table); BackupImage.Builder builder = BackupImage.newBuilder(); this.backupImage = builder.withBackupId(backup.getBackupId()).withType(backup.getType()) .withRootDir(backup.getBackupRootDir()).withTableList(tables) .withStartTime(backup.getStartTs()).withCompleteTime(backup.getCompleteTs()).build(); }
private boolean compare(BackupInfo one, BackupInfo two) { return one.getBackupId().equals(two.getBackupId()) && one.getType().equals(two.getType()) && one.getBackupRootDir().equals(two.getBackupRootDir()) && one.getStartTs() == two.getStartTs() && one.getCompleteTs() == two.getCompleteTs(); }
@Test public void testUpdateReadDeleteBackupStatus() throws IOException { BackupInfo ctx = createBackupInfo(); table.updateBackupInfo(ctx); BackupInfo readCtx = table.readBackupInfo(ctx.getBackupId()); assertTrue(compare(ctx, readCtx)); // try fake backup id readCtx = table.readBackupInfo("fake"); assertNull(readCtx); // delete backup info table.deleteBackupInfo(ctx.getBackupId()); readCtx = table.readBackupInfo(ctx.getBackupId()); assertNull(readCtx); cleanBackupTable(); }
@Test public void testFullBackupMultipleCommand() throws Exception { LOG.info("test full backup on a multiple tables with data: command-line"); try (BackupSystemTable table = new BackupSystemTable(TEST_UTIL.getConnection())) { int before = table.getBackupHistory().size(); String[] args = new String[] { "create", "full", BACKUP_ROOT_DIR, "-t", table1.getNameAsString() + "," + table2.getNameAsString() }; // Run backup int ret = ToolRunner.run(conf1, new BackupDriver(), args); assertTrue(ret == 0); List<BackupInfo> backups = table.getBackupHistory(); int after = table.getBackupHistory().size(); assertTrue(after == before + 1); for (BackupInfo data : backups) { String backupId = data.getBackupId(); assertTrue(checkSucceeded(backupId)); } } LOG.info("backup complete"); }
/** * Construct manifest for a ongoing backup. * @param backup The ongoing backup info */ public BackupManifest(BackupInfo backup) { BackupImage.Builder builder = BackupImage.newBuilder(); this.backupImage = builder.withBackupId(backup.getBackupId()).withType(backup.getType()) .withRootDir(backup.getBackupRootDir()).withTableList(backup.getTableNames()) .withStartTime(backup.getStartTs()).withCompleteTime(backup.getCompleteTs()).build(); }