1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.backup;
19
20 import java.io.IOException;
21 import java.util.List;
22
23 import org.apache.commons.cli.CommandLine;
24 import org.apache.commons.lang.StringUtils;
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.hadoop.conf.Configuration;
28 import org.apache.hadoop.hbase.HBaseConfiguration;
29 import org.apache.hadoop.hbase.TableName;
30 import org.apache.hadoop.hbase.backup.impl.BackupRestoreConstants;
31 import org.apache.hadoop.hbase.backup.impl.BackupSystemTable;
32 import org.apache.hadoop.hbase.backup.util.BackupServerUtil;
33 import org.apache.hadoop.hbase.client.Connection;
34 import org.apache.hadoop.hbase.client.ConnectionFactory;
35 import org.apache.hadoop.hbase.util.AbstractHBaseTool;
36 import org.apache.hadoop.hbase.util.LogUtils;
37 import org.apache.hadoop.util.ToolRunner;
38 import org.apache.log4j.Level;
39 import org.apache.log4j.Logger;
40
41 public class RestoreDriver extends AbstractHBaseTool {
42
43 private static final Log LOG = LogFactory.getLog(RestoreDriver.class);
44 private CommandLine cmd;
45
46 private static final String OPTION_OVERWRITE = "overwrite";
47 private static final String OPTION_CHECK = "check";
48 private static final String OPTION_AUTOMATIC = "automatic";
49 private static final String OPTION_SET = "set";
50 private static final String OPTION_DEBUG = "debug";
51
52
53 private static final String USAGE =
54 "Usage: hbase restore [-set set_name] <backup_root_path> <backup_id> <tables> [tableMapping] \n"
55 + " [-overwrite] [-check] [-automatic]\n"
56 + " backup_root_path The parent location where the backup images are stored\n"
57 + " backup_id The id identifying the backup image\n"
58 + " table(s) Table(s) from the backup image to be restored.\n"
59 + " Tables are separated by comma.\n"
60 + " Options:\n"
61 + " tableMapping A comma separated list of target tables.\n"
62 + " If specified, each table in <tables> must have a mapping.\n"
63 + " -overwrite With this option, restore overwrites to the existing table "
64 + "if there's any in\n"
65 + " restore target. The existing table must be online before restore.\n"
66 + " -check With this option, restore sequence and dependencies are checked\n"
67 + " and verified without executing the restore\n"
68 + " -set set_name Backup set to restore, mutually exclusive with table list <tables>.";
69
70
71 protected RestoreDriver() throws IOException
72 {
73 init();
74 }
75
76 protected void init() throws IOException {
77
78 addOptNoArg(OPTION_OVERWRITE,
79 "Overwrite the data if any of the restore target tables exists");
80 addOptNoArg(OPTION_CHECK, "Check restore sequence and dependencies");
81 addOptNoArg(OPTION_AUTOMATIC, "Restore all dependencies");
82 addOptNoArg(OPTION_DEBUG, "Enable debug logging");
83 addOptWithArg(OPTION_SET, "Backup set name");
84
85
86 LogUtils.disableUselessLoggers(LOG);
87 }
88
89 private int parseAndRun(String[] args) {
90
91
92 Logger backupClientLogger = Logger.getLogger("org.apache.hadoop.hbase.backup");
93 if (cmd.hasOption(OPTION_DEBUG)) {
94 backupClientLogger.setLevel(Level.DEBUG);
95 }
96
97
98 boolean isOverwrite = cmd.hasOption(OPTION_OVERWRITE);
99 if (isOverwrite) {
100 LOG.debug("Found -overwrite option in restore command, "
101 + "will overwrite to existing table if any in the restore target");
102 }
103
104
105 boolean check = cmd.hasOption(OPTION_CHECK);
106 if (check) {
107 LOG.debug("Found -check option in restore command, "
108 + "will check and verify the dependencies");
109 }
110
111 LOG.debug("Will automatically restore all the dependencies");
112
113
114 String[] remainArgs = cmd.getArgs();
115 if (remainArgs.length < 3 && !cmd.hasOption(OPTION_SET) ||
116 (cmd.hasOption(OPTION_SET) && remainArgs.length < 2)) {
117 System.out.println("ERROR: remain args length="+ remainArgs.length);
118 System.out.println(USAGE);
119 return -1;
120 }
121
122 String backupRootDir = remainArgs[0];
123 String backupId = remainArgs[1];
124 String tables = null;
125 String tableMapping = null;
126
127 if (cmd.hasOption(OPTION_SET)) {
128 String setName = cmd.getOptionValue(OPTION_SET);
129 try{
130 tables = getTablesForSet(setName, conf);
131 } catch(IOException e){
132 System.out.println("ERROR: "+ e.getMessage()+" for setName="+setName);
133 return -2;
134 }
135 if (tables == null) {
136 System.out.println("ERROR: Backup set '" + setName
137 + "' is either empty or does not exist");
138 return -3;
139 }
140 tableMapping = (remainArgs.length > 2) ? remainArgs[2] : null;
141 } else {
142 tables = remainArgs[2];
143 tableMapping = (remainArgs.length > 3) ? remainArgs[3] : null;
144 }
145
146 TableName[] sTableArray = BackupServerUtil.parseTableNames(tables);
147 TableName[] tTableArray = BackupServerUtil.parseTableNames(tableMapping);
148
149 if (sTableArray != null && tTableArray != null && (sTableArray.length != tTableArray.length)) {
150 System.out.println("ERROR: table mapping mismatch: " + tables + " : " + tableMapping);
151 System.out.println(USAGE);
152 return -4;
153 }
154
155
156 RestoreClient client = BackupRestoreClientFactory.getRestoreClient(getConf());
157 try{
158 client.restore(backupRootDir, backupId, check, sTableArray,
159 tTableArray, isOverwrite);
160 } catch (Exception e){
161 e.printStackTrace();
162 return -5;
163 }
164 return 0;
165 }
166
167 private String getTablesForSet(String name, Configuration conf) throws IOException {
168 try (final Connection conn = ConnectionFactory.createConnection(conf);
169 final BackupSystemTable table = new BackupSystemTable(conn)) {
170 List<TableName> tables = table.describeBackupSet(name);
171 if (tables == null) return null;
172 return StringUtils.join(tables, BackupRestoreConstants.TABLENAME_DELIMITER_IN_COMMAND);
173 }
174 }
175
176 @Override
177 protected void addOptions() {
178 }
179
180 @Override
181 protected void processOptions(CommandLine cmd) {
182 this.cmd = cmd;
183 }
184
185 @Override
186 protected int doWork() throws Exception {
187 return parseAndRun(cmd.getArgs());
188 }
189
190 public static void main(String[] args) throws Exception {
191 Configuration conf = HBaseConfiguration.create();
192 int ret = ToolRunner.run(conf, new RestoreDriver(), args);
193 System.exit(ret);
194 }
195 }