1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.client;
19
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.concurrent.Future;
25
26 import org.apache.commons.lang.StringUtils;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.fs.FileSystem;
30 import org.apache.hadoop.fs.Path;
31 import org.apache.hadoop.hbase.TableName;
32 import org.apache.hadoop.hbase.backup.BackupInfo;
33 import org.apache.hadoop.hbase.backup.BackupInfo.BackupState;
34 import org.apache.hadoop.hbase.backup.BackupRequest;
35 import org.apache.hadoop.hbase.backup.BackupRestoreClientFactory;
36 import org.apache.hadoop.hbase.backup.RestoreClient;
37 import org.apache.hadoop.hbase.backup.RestoreRequest;
38 import org.apache.hadoop.hbase.backup.impl.BackupSystemTable;
39 import org.apache.hadoop.hbase.backup.util.BackupClientUtil;
40 import org.apache.hadoop.hbase.backup.util.BackupSet;
41 import org.apache.hadoop.hbase.classification.InterfaceAudience;
42 import org.apache.hadoop.hbase.classification.InterfaceStability;
43
44
45
46
47
48
49
50
51
52
53 @InterfaceAudience.Private
54 @InterfaceStability.Evolving
55
56 public class HBaseBackupAdmin implements BackupAdmin {
57 private static final Log LOG = LogFactory.getLog(HBaseBackupAdmin.class);
58
59 private final HBaseAdmin admin;
60 private final Connection conn;
61
62 HBaseBackupAdmin(HBaseAdmin admin) {
63 this.admin = admin;
64 this.conn = admin.getConnection();
65 }
66
67
68 @Override
69 public void close() throws IOException {
70 }
71
72 @Override
73 public BackupInfo getBackupInfo(String backupId) throws IOException {
74 BackupInfo backupInfo = null;
75 try (final BackupSystemTable table = new BackupSystemTable(conn)) {
76 backupInfo = table.readBackupInfo(backupId);
77 return backupInfo;
78 }
79 }
80
81 @Override
82 public int getProgress(String backupId) throws IOException {
83 BackupInfo backupInfo = null;
84 try (final BackupSystemTable table = new BackupSystemTable(conn)) {
85 if (backupId == null) {
86 ArrayList<BackupInfo> recentSessions =
87 table.getBackupContexts(BackupState.RUNNING);
88 if (recentSessions.isEmpty()) {
89 LOG.warn("No ongoing sessions found.");
90 return -1;
91 }
92
93
94 return recentSessions.get(0).getProgress();
95 } else {
96
97 backupInfo = table.readBackupInfo(backupId);
98 if (backupInfo != null) {
99 return backupInfo.getProgress();
100 } else {
101 LOG.warn("No information found for backupID=" + backupId);
102 return -1;
103 }
104 }
105 }
106 }
107
108 @Override
109 public int deleteBackups(String[] backupIds) throws IOException {
110 BackupInfo backupInfo = null;
111 String backupId = null;
112 int totalDeleted = 0;
113 try (final BackupSystemTable table = new BackupSystemTable(conn)) {
114 for (int i = 0; i < backupIds.length; i++) {
115 backupId = backupIds[i];
116 LOG.info("Deleting backup for backupID=" + backupId + " ...");
117 backupInfo = table.readBackupInfo(backupId);
118 if (backupInfo != null) {
119 BackupClientUtil.cleanupBackupData(backupInfo, admin.getConfiguration());
120
121 Map<byte[], String> map = table.readBulkLoadedFiles(backupId);
122 FileSystem fs = FileSystem.get(conn.getConfiguration());
123 boolean succ = true;
124 int numDeleted = 0;
125 for (String f : map.values()) {
126 Path p = new Path(f);
127 try {
128 if (!fs.delete(p)) {
129 if (fs.exists(p)) {
130 LOG.warn(f + " was not deleted");
131 succ = false;
132 }
133 } else {
134 numDeleted++;
135 }
136 } catch (IOException ioe) {
137 LOG.warn(f + " was not deleted", ioe);
138 succ = false;
139 }
140 }
141 LOG.debug(numDeleted + " bulk loaded files out of " + map.size() + " were deleted");
142 if (succ) {
143 table.deleteBulkLoadedFiles(map);
144 }
145 table.deleteBackupInfo(backupInfo.getBackupId());
146 LOG.info("Delete backup for backupID=" + backupId + " completed.");
147 totalDeleted++;
148 } else {
149 LOG.warn("Delete backup failed: no information found for backupID=" + backupId);
150 }
151 }
152 }
153 return totalDeleted;
154 }
155
156 @Override
157 public List<BackupInfo> getHistory(int n) throws IOException {
158 try (final BackupSystemTable table = new BackupSystemTable(conn)) {
159 List<BackupInfo> history = table.getBackupHistory();
160 if( history.size() <= n) return history;
161 List<BackupInfo> list = new ArrayList<BackupInfo>();
162 for(int i=0; i < n; i++){
163 list.add(history.get(i));
164 }
165 return list;
166 }
167 }
168
169 @Override
170 public List<BackupSet> listBackupSets() throws IOException {
171 try (final BackupSystemTable table = new BackupSystemTable(conn)) {
172 List<String> list = table.listBackupSets();
173 List<BackupSet> bslist = new ArrayList<BackupSet>();
174 for (String s : list) {
175 List<TableName> tables = table.describeBackupSet(s);
176 if(tables != null){
177 bslist.add( new BackupSet(s, tables));
178 }
179 }
180 return bslist;
181 }
182 }
183
184 @Override
185 public BackupSet getBackupSet(String name) throws IOException {
186 try (final BackupSystemTable table = new BackupSystemTable(conn)) {
187 List<TableName> list = table.describeBackupSet(name);
188 if(list == null) return null;
189 return new BackupSet(name, list);
190 }
191 }
192
193 @Override
194 public boolean deleteBackupSet(String name) throws IOException {
195 try (final BackupSystemTable table = new BackupSystemTable(conn)) {
196 if(table.describeBackupSet(name) == null) {
197 return false;
198 }
199 table.deleteBackupSet(name);
200 return true;
201 }
202 }
203
204 @Override
205 public void addToBackupSet(String name, TableName[] tables) throws IOException {
206 String[] tableNames = new String[tables.length];
207 for(int i = 0; i < tables.length; i++){
208 tableNames[i] = tables[i].getNameAsString();
209 if (!admin.tableExists(tableNames[i])) {
210 throw new IOException("Cannot add " + tableNames[i] + " because it doesn't exist");
211 }
212 }
213 try (final BackupSystemTable table = new BackupSystemTable(conn)) {
214 table.addToBackupSet(name, tableNames);
215 LOG.info("Added tables ["+StringUtils.join(tableNames, " ")+"] to '" + name + "' backup set");
216 }
217 }
218
219 @Override
220 public void removeFromBackupSet(String name, String[] tables) throws IOException {
221 LOG.info("Removing tables ["+ StringUtils.join(tables, " ")+"] from '" + name + "'");
222 try (final BackupSystemTable table = new BackupSystemTable(conn)) {
223 table.removeFromBackupSet(name, tables);
224 LOG.info("Removing tables ["+ StringUtils.join(tables, " ")+"] from '" + name + "' completed.");
225 }
226 }
227
228 @Override
229 public void restore(RestoreRequest request) throws IOException {
230 RestoreClient client = BackupRestoreClientFactory.getRestoreClient(admin.getConfiguration());
231 client.restore(request.getBackupRootDir(),
232 request.getBackupId(),
233 request.isCheck(),
234 request.getFromTables(),
235 request.getToTables(),
236 request.isOverwrite());
237
238 }
239
240 @Override
241 public String backupTables(final BackupRequest userRequest)
242 throws IOException {
243 return admin.backupTables(userRequest);
244 }
245
246
247 @Override
248 public Future<String> backupTablesAsync(final BackupRequest userRequest)
249 throws IOException {
250 return admin.backupTablesAsync(userRequest);
251 }
252
253
254 }