Published site at d5aaeee88b331e064830a2774f4fed238631457c.
[hbase-site.git] / devapidocs / src-html / org / apache / hadoop / hbase / backup / impl / BackupCommands.BackupSetCommand.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2 <html lang="en">
3 <head>
4 <title>Source code</title>
5 <link rel="stylesheet" type="text/css" href="../../../../../../../stylesheet.css" title="Style">
6 </head>
7 <body>
8 <div class="sourceContainer">
9 <pre><span class="sourceLineNo">001</span>/**<a name="line.1"></a>
10 <span class="sourceLineNo">002</span> * Licensed to the Apache Software Foundation (ASF) under one<a name="line.2"></a>
11 <span class="sourceLineNo">003</span> * or more contributor license agreements. See the NOTICE file<a name="line.3"></a>
12 <span class="sourceLineNo">004</span> * distributed with this work for additional information<a name="line.4"></a>
13 <span class="sourceLineNo">005</span> * regarding copyright ownership. The ASF licenses this file<a name="line.5"></a>
14 <span class="sourceLineNo">006</span> * to you under the Apache License, Version 2.0 (the<a name="line.6"></a>
15 <span class="sourceLineNo">007</span> * "License"); you may not use this file except in compliance<a name="line.7"></a>
16 <span class="sourceLineNo">008</span> * with the License. You may obtain a copy of the License at<a name="line.8"></a>
17 <span class="sourceLineNo">009</span> *<a name="line.9"></a>
18 <span class="sourceLineNo">010</span> * http://www.apache.org/licenses/LICENSE-2.0<a name="line.10"></a>
19 <span class="sourceLineNo">011</span> *<a name="line.11"></a>
20 <span class="sourceLineNo">012</span> * Unless required by applicable law or agreed to in writing, software<a name="line.12"></a>
21 <span class="sourceLineNo">013</span> * distributed under the License is distributed on an "AS IS" BASIS,<a name="line.13"></a>
22 <span class="sourceLineNo">014</span> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<a name="line.14"></a>
23 <span class="sourceLineNo">015</span> * See the License for the specific language governing permissions and<a name="line.15"></a>
24 <span class="sourceLineNo">016</span> * limitations under the License.<a name="line.16"></a>
25 <span class="sourceLineNo">017</span> */<a name="line.17"></a>
26 <span class="sourceLineNo">018</span><a name="line.18"></a>
27 <span class="sourceLineNo">019</span>package org.apache.hadoop.hbase.backup.impl;<a name="line.19"></a>
28 <span class="sourceLineNo">020</span><a name="line.20"></a>
29 <span class="sourceLineNo">021</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_BANDWIDTH;<a name="line.21"></a>
30 <span class="sourceLineNo">022</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_BANDWIDTH_DESC;<a name="line.22"></a>
31 <span class="sourceLineNo">023</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_DEBUG;<a name="line.23"></a>
32 <span class="sourceLineNo">024</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_DEBUG_DESC;<a name="line.24"></a>
33 <span class="sourceLineNo">025</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_PATH;<a name="line.25"></a>
34 <span class="sourceLineNo">026</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_PATH_DESC;<a name="line.26"></a>
35 <span class="sourceLineNo">027</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_RECORD_NUMBER;<a name="line.27"></a>
36 <span class="sourceLineNo">028</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_RECORD_NUMBER_DESC;<a name="line.28"></a>
37 <span class="sourceLineNo">029</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_SET;<a name="line.29"></a>
38 <span class="sourceLineNo">030</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_SET_BACKUP_DESC;<a name="line.30"></a>
39 <span class="sourceLineNo">031</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_SET_DESC;<a name="line.31"></a>
40 <span class="sourceLineNo">032</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_TABLE;<a name="line.32"></a>
41 <span class="sourceLineNo">033</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_TABLE_DESC;<a name="line.33"></a>
42 <span class="sourceLineNo">034</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_TABLE_LIST_DESC;<a name="line.34"></a>
43 <span class="sourceLineNo">035</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_WORKERS;<a name="line.35"></a>
44 <span class="sourceLineNo">036</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_WORKERS_DESC;<a name="line.36"></a>
45 <span class="sourceLineNo">037</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_YARN_QUEUE_NAME;<a name="line.37"></a>
46 <span class="sourceLineNo">038</span>import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_YARN_QUEUE_NAME_DESC;<a name="line.38"></a>
47 <span class="sourceLineNo">039</span><a name="line.39"></a>
48 <span class="sourceLineNo">040</span>import java.io.IOException;<a name="line.40"></a>
49 <span class="sourceLineNo">041</span>import java.net.URI;<a name="line.41"></a>
50 <span class="sourceLineNo">042</span>import java.util.List;<a name="line.42"></a>
51 <span class="sourceLineNo">043</span><a name="line.43"></a>
52 <span class="sourceLineNo">044</span>import org.apache.commons.cli.CommandLine;<a name="line.44"></a>
53 <span class="sourceLineNo">045</span>import org.apache.commons.cli.HelpFormatter;<a name="line.45"></a>
54 <span class="sourceLineNo">046</span>import org.apache.commons.cli.Options;<a name="line.46"></a>
55 <span class="sourceLineNo">047</span>import org.apache.commons.lang3.StringUtils;<a name="line.47"></a>
56 <span class="sourceLineNo">048</span>import org.apache.hadoop.conf.Configuration;<a name="line.48"></a>
57 <span class="sourceLineNo">049</span>import org.apache.hadoop.conf.Configured;<a name="line.49"></a>
58 <span class="sourceLineNo">050</span>import org.apache.hadoop.fs.FileSystem;<a name="line.50"></a>
59 <span class="sourceLineNo">051</span>import org.apache.hadoop.fs.Path;<a name="line.51"></a>
60 <span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.HBaseConfiguration;<a name="line.52"></a>
61 <span class="sourceLineNo">053</span>import org.apache.hadoop.hbase.TableName;<a name="line.53"></a>
62 <span class="sourceLineNo">054</span>import org.apache.hadoop.hbase.backup.BackupAdmin;<a name="line.54"></a>
63 <span class="sourceLineNo">055</span>import org.apache.hadoop.hbase.backup.BackupInfo;<a name="line.55"></a>
64 <span class="sourceLineNo">056</span>import org.apache.hadoop.hbase.backup.BackupInfo.BackupState;<a name="line.56"></a>
65 <span class="sourceLineNo">057</span>import org.apache.hadoop.hbase.backup.BackupRequest;<a name="line.57"></a>
66 <span class="sourceLineNo">058</span>import org.apache.hadoop.hbase.backup.BackupRestoreConstants;<a name="line.58"></a>
67 <span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.backup.BackupRestoreConstants.BackupCommand;<a name="line.59"></a>
68 <span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.backup.BackupType;<a name="line.60"></a>
69 <span class="sourceLineNo">061</span>import org.apache.hadoop.hbase.backup.HBackupFileSystem;<a name="line.61"></a>
70 <span class="sourceLineNo">062</span>import org.apache.hadoop.hbase.backup.util.BackupSet;<a name="line.62"></a>
71 <span class="sourceLineNo">063</span>import org.apache.hadoop.hbase.backup.util.BackupUtils;<a name="line.63"></a>
72 <span class="sourceLineNo">064</span>import org.apache.hadoop.hbase.client.Connection;<a name="line.64"></a>
73 <span class="sourceLineNo">065</span>import org.apache.hadoop.hbase.client.ConnectionFactory;<a name="line.65"></a>
74 <span class="sourceLineNo">066</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.66"></a>
75 <span class="sourceLineNo">067</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.67"></a>
76 <span class="sourceLineNo">068</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.68"></a>
77 <span class="sourceLineNo">069</span><a name="line.69"></a>
78 <span class="sourceLineNo">070</span>/**<a name="line.70"></a>
79 <span class="sourceLineNo">071</span> * General backup commands, options and usage messages<a name="line.71"></a>
80 <span class="sourceLineNo">072</span> */<a name="line.72"></a>
81 <span class="sourceLineNo">073</span>@InterfaceAudience.Private<a name="line.73"></a>
82 <span class="sourceLineNo">074</span>public final class BackupCommands {<a name="line.74"></a>
83 <span class="sourceLineNo">075</span> public final static String INCORRECT_USAGE = "Incorrect usage";<a name="line.75"></a>
84 <span class="sourceLineNo">076</span><a name="line.76"></a>
85 <span class="sourceLineNo">077</span> public final static String TOP_LEVEL_NOT_ALLOWED =<a name="line.77"></a>
86 <span class="sourceLineNo">078</span> "Top level (root) folder is not allowed to be a backup destination";<a name="line.78"></a>
87 <span class="sourceLineNo">079</span><a name="line.79"></a>
88 <span class="sourceLineNo">080</span> public static final String USAGE = "Usage: hbase backup COMMAND [command-specific arguments]\n"<a name="line.80"></a>
89 <span class="sourceLineNo">081</span> + "where COMMAND is one of:\n" + " create create a new backup image\n"<a name="line.81"></a>
90 <span class="sourceLineNo">082</span> + " delete delete an existing backup image\n"<a name="line.82"></a>
91 <span class="sourceLineNo">083</span> + " describe show the detailed information of a backup image\n"<a name="line.83"></a>
92 <span class="sourceLineNo">084</span> + " history show history of all successful backups\n"<a name="line.84"></a>
93 <span class="sourceLineNo">085</span> + " progress show the progress of the latest backup request\n"<a name="line.85"></a>
94 <span class="sourceLineNo">086</span> + " set backup set management\n"<a name="line.86"></a>
95 <span class="sourceLineNo">087</span> + " repair repair backup system table\n"<a name="line.87"></a>
96 <span class="sourceLineNo">088</span> + " merge merge backup images\n"<a name="line.88"></a>
97 <span class="sourceLineNo">089</span> + "Run \'hbase backup COMMAND -h\' to see help message for each command\n";<a name="line.89"></a>
98 <span class="sourceLineNo">090</span><a name="line.90"></a>
99 <span class="sourceLineNo">091</span> public static final String CREATE_CMD_USAGE =<a name="line.91"></a>
100 <span class="sourceLineNo">092</span> "Usage: hbase backup create &lt;type&gt; &lt;backup_path&gt; [options]\n"<a name="line.92"></a>
101 <span class="sourceLineNo">093</span> + " type \"full\" to create a full backup image\n"<a name="line.93"></a>
102 <span class="sourceLineNo">094</span> + " \"incremental\" to create an incremental backup image\n"<a name="line.94"></a>
103 <span class="sourceLineNo">095</span> + " backup_path Full path to store the backup image\n";<a name="line.95"></a>
104 <span class="sourceLineNo">096</span><a name="line.96"></a>
105 <span class="sourceLineNo">097</span> public static final String PROGRESS_CMD_USAGE = "Usage: hbase backup progress &lt;backup_id&gt;\n"<a name="line.97"></a>
106 <span class="sourceLineNo">098</span> + " backup_id Backup image id (optional). If no id specified, the command will show\n"<a name="line.98"></a>
107 <span class="sourceLineNo">099</span> + " progress for currently running backup session.";<a name="line.99"></a>
108 <span class="sourceLineNo">100</span> public static final String NO_INFO_FOUND = "No info was found for backup id: ";<a name="line.100"></a>
109 <span class="sourceLineNo">101</span> public static final String NO_ACTIVE_SESSION_FOUND = "No active backup sessions found.";<a name="line.101"></a>
110 <span class="sourceLineNo">102</span><a name="line.102"></a>
111 <span class="sourceLineNo">103</span> public static final String DESCRIBE_CMD_USAGE = "Usage: hbase backup describe &lt;backup_id&gt;\n"<a name="line.103"></a>
112 <span class="sourceLineNo">104</span> + " backup_id Backup image id\n";<a name="line.104"></a>
113 <span class="sourceLineNo">105</span><a name="line.105"></a>
114 <span class="sourceLineNo">106</span> public static final String HISTORY_CMD_USAGE = "Usage: hbase backup history [options]";<a name="line.106"></a>
115 <span class="sourceLineNo">107</span><a name="line.107"></a>
116 <span class="sourceLineNo">108</span> public static final String DELETE_CMD_USAGE = "Usage: hbase backup delete &lt;backup_id&gt;\n"<a name="line.108"></a>
117 <span class="sourceLineNo">109</span> + " backup_id Backup image id\n";<a name="line.109"></a>
118 <span class="sourceLineNo">110</span><a name="line.110"></a>
119 <span class="sourceLineNo">111</span> public static final String REPAIR_CMD_USAGE = "Usage: hbase backup repair\n";<a name="line.111"></a>
120 <span class="sourceLineNo">112</span><a name="line.112"></a>
121 <span class="sourceLineNo">113</span> public static final String SET_CMD_USAGE = "Usage: hbase backup set COMMAND [name] [tables]\n"<a name="line.113"></a>
122 <span class="sourceLineNo">114</span> + " name Backup set name\n"<a name="line.114"></a>
123 <span class="sourceLineNo">115</span> + " tables Comma separated list of tables.\n" + "COMMAND is one of:\n"<a name="line.115"></a>
124 <span class="sourceLineNo">116</span> + " add add tables to a set, create a set if needed\n"<a name="line.116"></a>
125 <span class="sourceLineNo">117</span> + " remove remove tables from a set\n"<a name="line.117"></a>
126 <span class="sourceLineNo">118</span> + " list list all backup sets in the system\n"<a name="line.118"></a>
127 <span class="sourceLineNo">119</span> + " describe describe set\n" + " delete delete backup set\n";<a name="line.119"></a>
128 <span class="sourceLineNo">120</span> public static final String MERGE_CMD_USAGE = "Usage: hbase backup merge [backup_ids]\n"<a name="line.120"></a>
129 <span class="sourceLineNo">121</span> + " backup_ids Comma separated list of backup image ids.\n";<a name="line.121"></a>
130 <span class="sourceLineNo">122</span><a name="line.122"></a>
131 <span class="sourceLineNo">123</span> public static final String USAGE_FOOTER = "";<a name="line.123"></a>
132 <span class="sourceLineNo">124</span><a name="line.124"></a>
133 <span class="sourceLineNo">125</span> public static abstract class Command extends Configured {<a name="line.125"></a>
134 <span class="sourceLineNo">126</span> CommandLine cmdline;<a name="line.126"></a>
135 <span class="sourceLineNo">127</span> Connection conn;<a name="line.127"></a>
136 <span class="sourceLineNo">128</span><a name="line.128"></a>
137 <span class="sourceLineNo">129</span> Command(Configuration conf) {<a name="line.129"></a>
138 <span class="sourceLineNo">130</span> if (conf == null) {<a name="line.130"></a>
139 <span class="sourceLineNo">131</span> conf = HBaseConfiguration.create();<a name="line.131"></a>
140 <span class="sourceLineNo">132</span> }<a name="line.132"></a>
141 <span class="sourceLineNo">133</span> setConf(conf);<a name="line.133"></a>
142 <span class="sourceLineNo">134</span> }<a name="line.134"></a>
143 <span class="sourceLineNo">135</span><a name="line.135"></a>
144 <span class="sourceLineNo">136</span> public void execute() throws IOException {<a name="line.136"></a>
145 <span class="sourceLineNo">137</span> if (cmdline.hasOption("h") || cmdline.hasOption("help")) {<a name="line.137"></a>
146 <span class="sourceLineNo">138</span> printUsage();<a name="line.138"></a>
147 <span class="sourceLineNo">139</span> throw new IOException(INCORRECT_USAGE);<a name="line.139"></a>
148 <span class="sourceLineNo">140</span> }<a name="line.140"></a>
149 <span class="sourceLineNo">141</span><a name="line.141"></a>
150 <span class="sourceLineNo">142</span> // Create connection<a name="line.142"></a>
151 <span class="sourceLineNo">143</span> conn = ConnectionFactory.createConnection(getConf());<a name="line.143"></a>
152 <span class="sourceLineNo">144</span> if (requiresNoActiveSession()) {<a name="line.144"></a>
153 <span class="sourceLineNo">145</span> // Check active session<a name="line.145"></a>
154 <span class="sourceLineNo">146</span> try (BackupSystemTable table = new BackupSystemTable(conn)) {<a name="line.146"></a>
155 <span class="sourceLineNo">147</span> List&lt;BackupInfo&gt; sessions = table.getBackupInfos(BackupState.RUNNING);<a name="line.147"></a>
156 <span class="sourceLineNo">148</span><a name="line.148"></a>
157 <span class="sourceLineNo">149</span> if (sessions.size() &gt; 0) {<a name="line.149"></a>
158 <span class="sourceLineNo">150</span> System.err.println("Found backup session in a RUNNING state: ");<a name="line.150"></a>
159 <span class="sourceLineNo">151</span> System.err.println(sessions.get(0));<a name="line.151"></a>
160 <span class="sourceLineNo">152</span> System.err.println("This may indicate that a previous session has failed abnormally.");<a name="line.152"></a>
161 <span class="sourceLineNo">153</span> System.err.println("In this case, backup recovery is recommended.");<a name="line.153"></a>
162 <span class="sourceLineNo">154</span> throw new IOException("Active session found, aborted command execution");<a name="line.154"></a>
163 <span class="sourceLineNo">155</span> }<a name="line.155"></a>
164 <span class="sourceLineNo">156</span> }<a name="line.156"></a>
165 <span class="sourceLineNo">157</span> }<a name="line.157"></a>
166 <span class="sourceLineNo">158</span> if (requiresConsistentState()) {<a name="line.158"></a>
167 <span class="sourceLineNo">159</span> // Check failed delete<a name="line.159"></a>
168 <span class="sourceLineNo">160</span> try (BackupSystemTable table = new BackupSystemTable(conn)) {<a name="line.160"></a>
169 <span class="sourceLineNo">161</span> String[] ids = table.getListOfBackupIdsFromDeleteOperation();<a name="line.161"></a>
170 <span class="sourceLineNo">162</span><a name="line.162"></a>
171 <span class="sourceLineNo">163</span> if (ids != null &amp;&amp; ids.length &gt; 0) {<a name="line.163"></a>
172 <span class="sourceLineNo">164</span> System.err.println("Found failed backup DELETE coommand. ");<a name="line.164"></a>
173 <span class="sourceLineNo">165</span> System.err.println("Backup system recovery is required.");<a name="line.165"></a>
174 <span class="sourceLineNo">166</span> throw new IOException("Failed backup DELETE found, aborted command execution");<a name="line.166"></a>
175 <span class="sourceLineNo">167</span> }<a name="line.167"></a>
176 <span class="sourceLineNo">168</span><a name="line.168"></a>
177 <span class="sourceLineNo">169</span> ids = table.getListOfBackupIdsFromMergeOperation();<a name="line.169"></a>
178 <span class="sourceLineNo">170</span> if (ids != null &amp;&amp; ids.length &gt; 0) {<a name="line.170"></a>
179 <span class="sourceLineNo">171</span> System.err.println("Found failed backup MERGE coommand. ");<a name="line.171"></a>
180 <span class="sourceLineNo">172</span> System.err.println("Backup system recovery is required.");<a name="line.172"></a>
181 <span class="sourceLineNo">173</span> throw new IOException("Failed backup MERGE found, aborted command execution");<a name="line.173"></a>
182 <span class="sourceLineNo">174</span> }<a name="line.174"></a>
183 <span class="sourceLineNo">175</span> }<a name="line.175"></a>
184 <span class="sourceLineNo">176</span> }<a name="line.176"></a>
185 <span class="sourceLineNo">177</span> }<a name="line.177"></a>
186 <span class="sourceLineNo">178</span><a name="line.178"></a>
187 <span class="sourceLineNo">179</span> public void finish() throws IOException {<a name="line.179"></a>
188 <span class="sourceLineNo">180</span> if (conn != null) {<a name="line.180"></a>
189 <span class="sourceLineNo">181</span> conn.close();<a name="line.181"></a>
190 <span class="sourceLineNo">182</span> }<a name="line.182"></a>
191 <span class="sourceLineNo">183</span> }<a name="line.183"></a>
192 <span class="sourceLineNo">184</span><a name="line.184"></a>
193 <span class="sourceLineNo">185</span> protected abstract void printUsage();<a name="line.185"></a>
194 <span class="sourceLineNo">186</span><a name="line.186"></a>
195 <span class="sourceLineNo">187</span> /**<a name="line.187"></a>
196 <span class="sourceLineNo">188</span> * The command can't be run if active backup session is in progress<a name="line.188"></a>
197 <span class="sourceLineNo">189</span> * @return true if no active sessions are in progress<a name="line.189"></a>
198 <span class="sourceLineNo">190</span> */<a name="line.190"></a>
199 <span class="sourceLineNo">191</span> protected boolean requiresNoActiveSession() {<a name="line.191"></a>
200 <span class="sourceLineNo">192</span> return false;<a name="line.192"></a>
201 <span class="sourceLineNo">193</span> }<a name="line.193"></a>
202 <span class="sourceLineNo">194</span><a name="line.194"></a>
203 <span class="sourceLineNo">195</span> /**<a name="line.195"></a>
204 <span class="sourceLineNo">196</span> * Command requires consistent state of a backup system Backup system may become inconsistent<a name="line.196"></a>
205 <span class="sourceLineNo">197</span> * because of an abnormal termination of a backup session or delete command<a name="line.197"></a>
206 <span class="sourceLineNo">198</span> * @return true, if yes<a name="line.198"></a>
207 <span class="sourceLineNo">199</span> */<a name="line.199"></a>
208 <span class="sourceLineNo">200</span> protected boolean requiresConsistentState() {<a name="line.200"></a>
209 <span class="sourceLineNo">201</span> return false;<a name="line.201"></a>
210 <span class="sourceLineNo">202</span> }<a name="line.202"></a>
211 <span class="sourceLineNo">203</span> }<a name="line.203"></a>
212 <span class="sourceLineNo">204</span><a name="line.204"></a>
213 <span class="sourceLineNo">205</span> private BackupCommands() {<a name="line.205"></a>
214 <span class="sourceLineNo">206</span> throw new AssertionError("Instantiating utility class...");<a name="line.206"></a>
215 <span class="sourceLineNo">207</span> }<a name="line.207"></a>
216 <span class="sourceLineNo">208</span><a name="line.208"></a>
217 <span class="sourceLineNo">209</span> public static Command createCommand(Configuration conf, BackupCommand type, CommandLine cmdline) {<a name="line.209"></a>
218 <span class="sourceLineNo">210</span> Command cmd;<a name="line.210"></a>
219 <span class="sourceLineNo">211</span> switch (type) {<a name="line.211"></a>
220 <span class="sourceLineNo">212</span> case CREATE:<a name="line.212"></a>
221 <span class="sourceLineNo">213</span> cmd = new CreateCommand(conf, cmdline);<a name="line.213"></a>
222 <span class="sourceLineNo">214</span> break;<a name="line.214"></a>
223 <span class="sourceLineNo">215</span> case DESCRIBE:<a name="line.215"></a>
224 <span class="sourceLineNo">216</span> cmd = new DescribeCommand(conf, cmdline);<a name="line.216"></a>
225 <span class="sourceLineNo">217</span> break;<a name="line.217"></a>
226 <span class="sourceLineNo">218</span> case PROGRESS:<a name="line.218"></a>
227 <span class="sourceLineNo">219</span> cmd = new ProgressCommand(conf, cmdline);<a name="line.219"></a>
228 <span class="sourceLineNo">220</span> break;<a name="line.220"></a>
229 <span class="sourceLineNo">221</span> case DELETE:<a name="line.221"></a>
230 <span class="sourceLineNo">222</span> cmd = new DeleteCommand(conf, cmdline);<a name="line.222"></a>
231 <span class="sourceLineNo">223</span> break;<a name="line.223"></a>
232 <span class="sourceLineNo">224</span> case HISTORY:<a name="line.224"></a>
233 <span class="sourceLineNo">225</span> cmd = new HistoryCommand(conf, cmdline);<a name="line.225"></a>
234 <span class="sourceLineNo">226</span> break;<a name="line.226"></a>
235 <span class="sourceLineNo">227</span> case SET:<a name="line.227"></a>
236 <span class="sourceLineNo">228</span> cmd = new BackupSetCommand(conf, cmdline);<a name="line.228"></a>
237 <span class="sourceLineNo">229</span> break;<a name="line.229"></a>
238 <span class="sourceLineNo">230</span> case REPAIR:<a name="line.230"></a>
239 <span class="sourceLineNo">231</span> cmd = new RepairCommand(conf, cmdline);<a name="line.231"></a>
240 <span class="sourceLineNo">232</span> break;<a name="line.232"></a>
241 <span class="sourceLineNo">233</span> case MERGE:<a name="line.233"></a>
242 <span class="sourceLineNo">234</span> cmd = new MergeCommand(conf, cmdline);<a name="line.234"></a>
243 <span class="sourceLineNo">235</span> break;<a name="line.235"></a>
244 <span class="sourceLineNo">236</span> case HELP:<a name="line.236"></a>
245 <span class="sourceLineNo">237</span> default:<a name="line.237"></a>
246 <span class="sourceLineNo">238</span> cmd = new HelpCommand(conf, cmdline);<a name="line.238"></a>
247 <span class="sourceLineNo">239</span> break;<a name="line.239"></a>
248 <span class="sourceLineNo">240</span> }<a name="line.240"></a>
249 <span class="sourceLineNo">241</span> return cmd;<a name="line.241"></a>
250 <span class="sourceLineNo">242</span> }<a name="line.242"></a>
251 <span class="sourceLineNo">243</span><a name="line.243"></a>
252 <span class="sourceLineNo">244</span> static int numOfArgs(String[] args) {<a name="line.244"></a>
253 <span class="sourceLineNo">245</span> if (args == null) {<a name="line.245"></a>
254 <span class="sourceLineNo">246</span> return 0;<a name="line.246"></a>
255 <span class="sourceLineNo">247</span> }<a name="line.247"></a>
256 <span class="sourceLineNo">248</span><a name="line.248"></a>
257 <span class="sourceLineNo">249</span> return args.length;<a name="line.249"></a>
258 <span class="sourceLineNo">250</span> }<a name="line.250"></a>
259 <span class="sourceLineNo">251</span><a name="line.251"></a>
260 <span class="sourceLineNo">252</span> public static class CreateCommand extends Command {<a name="line.252"></a>
261 <span class="sourceLineNo">253</span> CreateCommand(Configuration conf, CommandLine cmdline) {<a name="line.253"></a>
262 <span class="sourceLineNo">254</span> super(conf);<a name="line.254"></a>
263 <span class="sourceLineNo">255</span> this.cmdline = cmdline;<a name="line.255"></a>
264 <span class="sourceLineNo">256</span> }<a name="line.256"></a>
265 <span class="sourceLineNo">257</span><a name="line.257"></a>
266 <span class="sourceLineNo">258</span> @Override<a name="line.258"></a>
267 <span class="sourceLineNo">259</span> protected boolean requiresNoActiveSession() {<a name="line.259"></a>
268 <span class="sourceLineNo">260</span> return true;<a name="line.260"></a>
269 <span class="sourceLineNo">261</span> }<a name="line.261"></a>
270 <span class="sourceLineNo">262</span><a name="line.262"></a>
271 <span class="sourceLineNo">263</span> @Override<a name="line.263"></a>
272 <span class="sourceLineNo">264</span> protected boolean requiresConsistentState() {<a name="line.264"></a>
273 <span class="sourceLineNo">265</span> return true;<a name="line.265"></a>
274 <span class="sourceLineNo">266</span> }<a name="line.266"></a>
275 <span class="sourceLineNo">267</span><a name="line.267"></a>
276 <span class="sourceLineNo">268</span> @Override<a name="line.268"></a>
277 <span class="sourceLineNo">269</span> public void execute() throws IOException {<a name="line.269"></a>
278 <span class="sourceLineNo">270</span> if (cmdline == null || cmdline.getArgs() == null) {<a name="line.270"></a>
279 <span class="sourceLineNo">271</span> printUsage();<a name="line.271"></a>
280 <span class="sourceLineNo">272</span> throw new IOException(INCORRECT_USAGE);<a name="line.272"></a>
281 <span class="sourceLineNo">273</span> }<a name="line.273"></a>
282 <span class="sourceLineNo">274</span> String[] args = cmdline.getArgs();<a name="line.274"></a>
283 <span class="sourceLineNo">275</span> if (args.length != 3) {<a name="line.275"></a>
284 <span class="sourceLineNo">276</span> printUsage();<a name="line.276"></a>
285 <span class="sourceLineNo">277</span> throw new IOException(INCORRECT_USAGE);<a name="line.277"></a>
286 <span class="sourceLineNo">278</span> }<a name="line.278"></a>
287 <span class="sourceLineNo">279</span><a name="line.279"></a>
288 <span class="sourceLineNo">280</span> if (!BackupType.FULL.toString().equalsIgnoreCase(args[1])<a name="line.280"></a>
289 <span class="sourceLineNo">281</span> &amp;&amp; !BackupType.INCREMENTAL.toString().equalsIgnoreCase(args[1])) {<a name="line.281"></a>
290 <span class="sourceLineNo">282</span> System.out.println("ERROR: invalid backup type: " + args[1]);<a name="line.282"></a>
291 <span class="sourceLineNo">283</span> printUsage();<a name="line.283"></a>
292 <span class="sourceLineNo">284</span> throw new IOException(INCORRECT_USAGE);<a name="line.284"></a>
293 <span class="sourceLineNo">285</span> }<a name="line.285"></a>
294 <span class="sourceLineNo">286</span> if (!verifyPath(args[2])) {<a name="line.286"></a>
295 <span class="sourceLineNo">287</span> System.out.println("ERROR: invalid backup destination: " + args[2]);<a name="line.287"></a>
296 <span class="sourceLineNo">288</span> printUsage();<a name="line.288"></a>
297 <span class="sourceLineNo">289</span> throw new IOException(INCORRECT_USAGE);<a name="line.289"></a>
298 <span class="sourceLineNo">290</span> }<a name="line.290"></a>
299 <span class="sourceLineNo">291</span> String targetBackupDir = args[2];<a name="line.291"></a>
300 <span class="sourceLineNo">292</span> // Check if backup destination is top level (root) folder - not allowed<a name="line.292"></a>
301 <span class="sourceLineNo">293</span> if (isRootFolder(targetBackupDir)) {<a name="line.293"></a>
302 <span class="sourceLineNo">294</span> throw new IOException(TOP_LEVEL_NOT_ALLOWED);<a name="line.294"></a>
303 <span class="sourceLineNo">295</span> }<a name="line.295"></a>
304 <span class="sourceLineNo">296</span> String tables;<a name="line.296"></a>
305 <span class="sourceLineNo">297</span><a name="line.297"></a>
306 <span class="sourceLineNo">298</span> // Check if we have both: backup set and list of tables<a name="line.298"></a>
307 <span class="sourceLineNo">299</span> if (cmdline.hasOption(OPTION_TABLE) &amp;&amp; cmdline.hasOption(OPTION_SET)) {<a name="line.299"></a>
308 <span class="sourceLineNo">300</span> System.out.println("ERROR: You can specify either backup set or list"<a name="line.300"></a>
309 <span class="sourceLineNo">301</span> + " of tables, but not both");<a name="line.301"></a>
310 <span class="sourceLineNo">302</span> printUsage();<a name="line.302"></a>
311 <span class="sourceLineNo">303</span> throw new IOException(INCORRECT_USAGE);<a name="line.303"></a>
312 <span class="sourceLineNo">304</span> }<a name="line.304"></a>
313 <span class="sourceLineNo">305</span> // Creates connection<a name="line.305"></a>
314 <span class="sourceLineNo">306</span> super.execute();<a name="line.306"></a>
315 <span class="sourceLineNo">307</span> // Check backup set<a name="line.307"></a>
316 <span class="sourceLineNo">308</span> String setName = null;<a name="line.308"></a>
317 <span class="sourceLineNo">309</span> if (cmdline.hasOption(OPTION_SET)) {<a name="line.309"></a>
318 <span class="sourceLineNo">310</span> setName = cmdline.getOptionValue(OPTION_SET);<a name="line.310"></a>
319 <span class="sourceLineNo">311</span> tables = getTablesForSet(setName, getConf());<a name="line.311"></a>
320 <span class="sourceLineNo">312</span><a name="line.312"></a>
321 <span class="sourceLineNo">313</span> if (tables == null) {<a name="line.313"></a>
322 <span class="sourceLineNo">314</span> System.out.println("ERROR: Backup set '" + setName<a name="line.314"></a>
323 <span class="sourceLineNo">315</span> + "' is either empty or does not exist");<a name="line.315"></a>
324 <span class="sourceLineNo">316</span> printUsage();<a name="line.316"></a>
325 <span class="sourceLineNo">317</span> throw new IOException(INCORRECT_USAGE);<a name="line.317"></a>
326 <span class="sourceLineNo">318</span> }<a name="line.318"></a>
327 <span class="sourceLineNo">319</span> } else {<a name="line.319"></a>
328 <span class="sourceLineNo">320</span> tables = cmdline.getOptionValue(OPTION_TABLE);<a name="line.320"></a>
329 <span class="sourceLineNo">321</span> }<a name="line.321"></a>
330 <span class="sourceLineNo">322</span> int bandwidth =<a name="line.322"></a>
331 <span class="sourceLineNo">323</span> cmdline.hasOption(OPTION_BANDWIDTH) ? Integer.parseInt(cmdline<a name="line.323"></a>
332 <span class="sourceLineNo">324</span> .getOptionValue(OPTION_BANDWIDTH)) : -1;<a name="line.324"></a>
333 <span class="sourceLineNo">325</span> int workers =<a name="line.325"></a>
334 <span class="sourceLineNo">326</span> cmdline.hasOption(OPTION_WORKERS) ? Integer.parseInt(cmdline<a name="line.326"></a>
335 <span class="sourceLineNo">327</span> .getOptionValue(OPTION_WORKERS)) : -1;<a name="line.327"></a>
336 <span class="sourceLineNo">328</span><a name="line.328"></a>
337 <span class="sourceLineNo">329</span> if (cmdline.hasOption(OPTION_YARN_QUEUE_NAME)) {<a name="line.329"></a>
338 <span class="sourceLineNo">330</span> String queueName = cmdline.getOptionValue(OPTION_YARN_QUEUE_NAME);<a name="line.330"></a>
339 <span class="sourceLineNo">331</span> // Set system property value for MR job<a name="line.331"></a>
340 <span class="sourceLineNo">332</span> System.setProperty("mapreduce.job.queuename", queueName);<a name="line.332"></a>
341 <span class="sourceLineNo">333</span> }<a name="line.333"></a>
342 <span class="sourceLineNo">334</span><a name="line.334"></a>
343 <span class="sourceLineNo">335</span> try (BackupAdminImpl admin = new BackupAdminImpl(conn)) {<a name="line.335"></a>
344 <span class="sourceLineNo">336</span> BackupRequest.Builder builder = new BackupRequest.Builder();<a name="line.336"></a>
345 <span class="sourceLineNo">337</span> BackupRequest request =<a name="line.337"></a>
346 <span class="sourceLineNo">338</span> builder<a name="line.338"></a>
347 <span class="sourceLineNo">339</span> .withBackupType(BackupType.valueOf(args[1].toUpperCase()))<a name="line.339"></a>
348 <span class="sourceLineNo">340</span> .withTableList(<a name="line.340"></a>
349 <span class="sourceLineNo">341</span> tables != null ? Lists.newArrayList(BackupUtils.parseTableNames(tables)) : null)<a name="line.341"></a>
350 <span class="sourceLineNo">342</span> .withTargetRootDir(targetBackupDir).withTotalTasks(workers)<a name="line.342"></a>
351 <span class="sourceLineNo">343</span> .withBandwidthPerTasks(bandwidth).withBackupSetName(setName).build();<a name="line.343"></a>
352 <span class="sourceLineNo">344</span> String backupId = admin.backupTables(request);<a name="line.344"></a>
353 <span class="sourceLineNo">345</span> System.out.println("Backup session " + backupId + " finished. Status: SUCCESS");<a name="line.345"></a>
354 <span class="sourceLineNo">346</span> } catch (IOException e) {<a name="line.346"></a>
355 <span class="sourceLineNo">347</span> System.out.println("Backup session finished. Status: FAILURE");<a name="line.347"></a>
356 <span class="sourceLineNo">348</span> throw e;<a name="line.348"></a>
357 <span class="sourceLineNo">349</span> }<a name="line.349"></a>
358 <span class="sourceLineNo">350</span> }<a name="line.350"></a>
359 <span class="sourceLineNo">351</span><a name="line.351"></a>
360 <span class="sourceLineNo">352</span> private boolean isRootFolder(String targetBackupDir) {<a name="line.352"></a>
361 <span class="sourceLineNo">353</span> Path p = new Path(targetBackupDir);<a name="line.353"></a>
362 <span class="sourceLineNo">354</span> return p.isRoot();<a name="line.354"></a>
363 <span class="sourceLineNo">355</span> }<a name="line.355"></a>
364 <span class="sourceLineNo">356</span><a name="line.356"></a>
365 <span class="sourceLineNo">357</span> private boolean verifyPath(String path) {<a name="line.357"></a>
366 <span class="sourceLineNo">358</span> try {<a name="line.358"></a>
367 <span class="sourceLineNo">359</span> Path p = new Path(path);<a name="line.359"></a>
368 <span class="sourceLineNo">360</span> Configuration conf = getConf() != null ? getConf() : HBaseConfiguration.create();<a name="line.360"></a>
369 <span class="sourceLineNo">361</span> URI uri = p.toUri();<a name="line.361"></a>
370 <span class="sourceLineNo">362</span><a name="line.362"></a>
371 <span class="sourceLineNo">363</span> if (uri.getScheme() == null) {<a name="line.363"></a>
372 <span class="sourceLineNo">364</span> return false;<a name="line.364"></a>
373 <span class="sourceLineNo">365</span> }<a name="line.365"></a>
374 <span class="sourceLineNo">366</span><a name="line.366"></a>
375 <span class="sourceLineNo">367</span> FileSystem.get(uri, conf);<a name="line.367"></a>
376 <span class="sourceLineNo">368</span> return true;<a name="line.368"></a>
377 <span class="sourceLineNo">369</span> } catch (Exception e) {<a name="line.369"></a>
378 <span class="sourceLineNo">370</span> return false;<a name="line.370"></a>
379 <span class="sourceLineNo">371</span> }<a name="line.371"></a>
380 <span class="sourceLineNo">372</span> }<a name="line.372"></a>
381 <span class="sourceLineNo">373</span><a name="line.373"></a>
382 <span class="sourceLineNo">374</span> private String getTablesForSet(String name, Configuration conf) throws IOException {<a name="line.374"></a>
383 <span class="sourceLineNo">375</span> try (final BackupSystemTable table = new BackupSystemTable(conn)) {<a name="line.375"></a>
384 <span class="sourceLineNo">376</span> List&lt;TableName&gt; tables = table.describeBackupSet(name);<a name="line.376"></a>
385 <span class="sourceLineNo">377</span><a name="line.377"></a>
386 <span class="sourceLineNo">378</span> if (tables == null) {<a name="line.378"></a>
387 <span class="sourceLineNo">379</span> return null;<a name="line.379"></a>
388 <span class="sourceLineNo">380</span> }<a name="line.380"></a>
389 <span class="sourceLineNo">381</span><a name="line.381"></a>
390 <span class="sourceLineNo">382</span> return StringUtils.join(tables, BackupRestoreConstants.TABLENAME_DELIMITER_IN_COMMAND);<a name="line.382"></a>
391 <span class="sourceLineNo">383</span> }<a name="line.383"></a>
392 <span class="sourceLineNo">384</span> }<a name="line.384"></a>
393 <span class="sourceLineNo">385</span><a name="line.385"></a>
394 <span class="sourceLineNo">386</span> @Override<a name="line.386"></a>
395 <span class="sourceLineNo">387</span> protected void printUsage() {<a name="line.387"></a>
396 <span class="sourceLineNo">388</span> System.out.println(CREATE_CMD_USAGE);<a name="line.388"></a>
397 <span class="sourceLineNo">389</span> Options options = new Options();<a name="line.389"></a>
398 <span class="sourceLineNo">390</span> options.addOption(OPTION_WORKERS, true, OPTION_WORKERS_DESC);<a name="line.390"></a>
399 <span class="sourceLineNo">391</span> options.addOption(OPTION_BANDWIDTH, true, OPTION_BANDWIDTH_DESC);<a name="line.391"></a>
400 <span class="sourceLineNo">392</span> options.addOption(OPTION_SET, true, OPTION_SET_BACKUP_DESC);<a name="line.392"></a>
401 <span class="sourceLineNo">393</span> options.addOption(OPTION_TABLE, true, OPTION_TABLE_LIST_DESC);<a name="line.393"></a>
402 <span class="sourceLineNo">394</span> options.addOption(OPTION_YARN_QUEUE_NAME, true, OPTION_YARN_QUEUE_NAME_DESC);<a name="line.394"></a>
403 <span class="sourceLineNo">395</span> options.addOption(OPTION_DEBUG, false, OPTION_DEBUG_DESC);<a name="line.395"></a>
404 <span class="sourceLineNo">396</span><a name="line.396"></a>
405 <span class="sourceLineNo">397</span> HelpFormatter helpFormatter = new HelpFormatter();<a name="line.397"></a>
406 <span class="sourceLineNo">398</span> helpFormatter.setLeftPadding(2);<a name="line.398"></a>
407 <span class="sourceLineNo">399</span> helpFormatter.setDescPadding(8);<a name="line.399"></a>
408 <span class="sourceLineNo">400</span> helpFormatter.setWidth(100);<a name="line.400"></a>
409 <span class="sourceLineNo">401</span> helpFormatter.setSyntaxPrefix("Options:");<a name="line.401"></a>
410 <span class="sourceLineNo">402</span> helpFormatter.printHelp(" ", null, options, USAGE_FOOTER);<a name="line.402"></a>
411 <span class="sourceLineNo">403</span> }<a name="line.403"></a>
412 <span class="sourceLineNo">404</span> }<a name="line.404"></a>
413 <span class="sourceLineNo">405</span><a name="line.405"></a>
414 <span class="sourceLineNo">406</span> public static class HelpCommand extends Command {<a name="line.406"></a>
415 <span class="sourceLineNo">407</span> HelpCommand(Configuration conf, CommandLine cmdline) {<a name="line.407"></a>
416 <span class="sourceLineNo">408</span> super(conf);<a name="line.408"></a>
417 <span class="sourceLineNo">409</span> this.cmdline = cmdline;<a name="line.409"></a>
418 <span class="sourceLineNo">410</span> }<a name="line.410"></a>
419 <span class="sourceLineNo">411</span><a name="line.411"></a>
420 <span class="sourceLineNo">412</span> @Override<a name="line.412"></a>
421 <span class="sourceLineNo">413</span> public void execute() throws IOException {<a name="line.413"></a>
422 <span class="sourceLineNo">414</span> if (cmdline == null) {<a name="line.414"></a>
423 <span class="sourceLineNo">415</span> printUsage();<a name="line.415"></a>
424 <span class="sourceLineNo">416</span> throw new IOException(INCORRECT_USAGE);<a name="line.416"></a>
425 <span class="sourceLineNo">417</span> }<a name="line.417"></a>
426 <span class="sourceLineNo">418</span><a name="line.418"></a>
427 <span class="sourceLineNo">419</span> String[] args = cmdline.getArgs();<a name="line.419"></a>
428 <span class="sourceLineNo">420</span> if (args == null || args.length == 0) {<a name="line.420"></a>
429 <span class="sourceLineNo">421</span> printUsage();<a name="line.421"></a>
430 <span class="sourceLineNo">422</span> throw new IOException(INCORRECT_USAGE);<a name="line.422"></a>
431 <span class="sourceLineNo">423</span> }<a name="line.423"></a>
432 <span class="sourceLineNo">424</span><a name="line.424"></a>
433 <span class="sourceLineNo">425</span> if (args.length != 2) {<a name="line.425"></a>
434 <span class="sourceLineNo">426</span> System.out.println("ERROR: Only supports help message of a single command type");<a name="line.426"></a>
435 <span class="sourceLineNo">427</span> printUsage();<a name="line.427"></a>
436 <span class="sourceLineNo">428</span> throw new IOException(INCORRECT_USAGE);<a name="line.428"></a>
437 <span class="sourceLineNo">429</span> }<a name="line.429"></a>
438 <span class="sourceLineNo">430</span><a name="line.430"></a>
439 <span class="sourceLineNo">431</span> String type = args[1];<a name="line.431"></a>
440 <span class="sourceLineNo">432</span><a name="line.432"></a>
441 <span class="sourceLineNo">433</span> if (BackupCommand.CREATE.name().equalsIgnoreCase(type)) {<a name="line.433"></a>
442 <span class="sourceLineNo">434</span> System.out.println(CREATE_CMD_USAGE);<a name="line.434"></a>
443 <span class="sourceLineNo">435</span> } else if (BackupCommand.DESCRIBE.name().equalsIgnoreCase(type)) {<a name="line.435"></a>
444 <span class="sourceLineNo">436</span> System.out.println(DESCRIBE_CMD_USAGE);<a name="line.436"></a>
445 <span class="sourceLineNo">437</span> } else if (BackupCommand.HISTORY.name().equalsIgnoreCase(type)) {<a name="line.437"></a>
446 <span class="sourceLineNo">438</span> System.out.println(HISTORY_CMD_USAGE);<a name="line.438"></a>
447 <span class="sourceLineNo">439</span> } else if (BackupCommand.PROGRESS.name().equalsIgnoreCase(type)) {<a name="line.439"></a>
448 <span class="sourceLineNo">440</span> System.out.println(PROGRESS_CMD_USAGE);<a name="line.440"></a>
449 <span class="sourceLineNo">441</span> } else if (BackupCommand.DELETE.name().equalsIgnoreCase(type)) {<a name="line.441"></a>
450 <span class="sourceLineNo">442</span> System.out.println(DELETE_CMD_USAGE);<a name="line.442"></a>
451 <span class="sourceLineNo">443</span> } else if (BackupCommand.SET.name().equalsIgnoreCase(type)) {<a name="line.443"></a>
452 <span class="sourceLineNo">444</span> System.out.println(SET_CMD_USAGE);<a name="line.444"></a>
453 <span class="sourceLineNo">445</span> } else {<a name="line.445"></a>
454 <span class="sourceLineNo">446</span> System.out.println("Unknown command : " + type);<a name="line.446"></a>
455 <span class="sourceLineNo">447</span> printUsage();<a name="line.447"></a>
456 <span class="sourceLineNo">448</span> }<a name="line.448"></a>
457 <span class="sourceLineNo">449</span> }<a name="line.449"></a>
458 <span class="sourceLineNo">450</span><a name="line.450"></a>
459 <span class="sourceLineNo">451</span> @Override<a name="line.451"></a>
460 <span class="sourceLineNo">452</span> protected void printUsage() {<a name="line.452"></a>
461 <span class="sourceLineNo">453</span> System.out.println(USAGE);<a name="line.453"></a>
462 <span class="sourceLineNo">454</span> }<a name="line.454"></a>
463 <span class="sourceLineNo">455</span> }<a name="line.455"></a>
464 <span class="sourceLineNo">456</span><a name="line.456"></a>
465 <span class="sourceLineNo">457</span> public static class DescribeCommand extends Command {<a name="line.457"></a>
466 <span class="sourceLineNo">458</span> DescribeCommand(Configuration conf, CommandLine cmdline) {<a name="line.458"></a>
467 <span class="sourceLineNo">459</span> super(conf);<a name="line.459"></a>
468 <span class="sourceLineNo">460</span> this.cmdline = cmdline;<a name="line.460"></a>
469 <span class="sourceLineNo">461</span> }<a name="line.461"></a>
470 <span class="sourceLineNo">462</span><a name="line.462"></a>
471 <span class="sourceLineNo">463</span> @Override<a name="line.463"></a>
472 <span class="sourceLineNo">464</span> public void execute() throws IOException {<a name="line.464"></a>
473 <span class="sourceLineNo">465</span> if (cmdline == null || cmdline.getArgs() == null) {<a name="line.465"></a>
474 <span class="sourceLineNo">466</span> printUsage();<a name="line.466"></a>
475 <span class="sourceLineNo">467</span> throw new IOException(INCORRECT_USAGE);<a name="line.467"></a>
476 <span class="sourceLineNo">468</span> }<a name="line.468"></a>
477 <span class="sourceLineNo">469</span> String[] args = cmdline.getArgs();<a name="line.469"></a>
478 <span class="sourceLineNo">470</span> if (args.length != 2) {<a name="line.470"></a>
479 <span class="sourceLineNo">471</span> printUsage();<a name="line.471"></a>
480 <span class="sourceLineNo">472</span> throw new IOException(INCORRECT_USAGE);<a name="line.472"></a>
481 <span class="sourceLineNo">473</span> }<a name="line.473"></a>
482 <span class="sourceLineNo">474</span><a name="line.474"></a>
483 <span class="sourceLineNo">475</span> super.execute();<a name="line.475"></a>
484 <span class="sourceLineNo">476</span><a name="line.476"></a>
485 <span class="sourceLineNo">477</span> String backupId = args[1];<a name="line.477"></a>
486 <span class="sourceLineNo">478</span> try (final BackupSystemTable sysTable = new BackupSystemTable(conn)) {<a name="line.478"></a>
487 <span class="sourceLineNo">479</span> BackupInfo info = sysTable.readBackupInfo(backupId);<a name="line.479"></a>
488 <span class="sourceLineNo">480</span> if (info == null) {<a name="line.480"></a>
489 <span class="sourceLineNo">481</span> System.out.println("ERROR: " + backupId + " does not exist");<a name="line.481"></a>
490 <span class="sourceLineNo">482</span> printUsage();<a name="line.482"></a>
491 <span class="sourceLineNo">483</span> throw new IOException(INCORRECT_USAGE);<a name="line.483"></a>
492 <span class="sourceLineNo">484</span> }<a name="line.484"></a>
493 <span class="sourceLineNo">485</span> System.out.println(info.getShortDescription());<a name="line.485"></a>
494 <span class="sourceLineNo">486</span> }<a name="line.486"></a>
495 <span class="sourceLineNo">487</span> }<a name="line.487"></a>
496 <span class="sourceLineNo">488</span><a name="line.488"></a>
497 <span class="sourceLineNo">489</span> @Override<a name="line.489"></a>
498 <span class="sourceLineNo">490</span> protected void printUsage() {<a name="line.490"></a>
499 <span class="sourceLineNo">491</span> System.out.println(DESCRIBE_CMD_USAGE);<a name="line.491"></a>
500 <span class="sourceLineNo">492</span> }<a name="line.492"></a>
501 <span class="sourceLineNo">493</span> }<a name="line.493"></a>
502 <span class="sourceLineNo">494</span><a name="line.494"></a>
503 <span class="sourceLineNo">495</span> public static class ProgressCommand extends Command {<a name="line.495"></a>
504 <span class="sourceLineNo">496</span> ProgressCommand(Configuration conf, CommandLine cmdline) {<a name="line.496"></a>
505 <span class="sourceLineNo">497</span> super(conf);<a name="line.497"></a>
506 <span class="sourceLineNo">498</span> this.cmdline = cmdline;<a name="line.498"></a>
507 <span class="sourceLineNo">499</span> }<a name="line.499"></a>
508 <span class="sourceLineNo">500</span><a name="line.500"></a>
509 <span class="sourceLineNo">501</span> @Override<a name="line.501"></a>
510 <span class="sourceLineNo">502</span> public void execute() throws IOException {<a name="line.502"></a>
511 <span class="sourceLineNo">503</span><a name="line.503"></a>
512 <span class="sourceLineNo">504</span> if (cmdline == null || cmdline.getArgs() == null || cmdline.getArgs().length == 1) {<a name="line.504"></a>
513 <span class="sourceLineNo">505</span> System.out.println("No backup id was specified, "<a name="line.505"></a>
514 <span class="sourceLineNo">506</span> + "will retrieve the most recent (ongoing) session");<a name="line.506"></a>
515 <span class="sourceLineNo">507</span> }<a name="line.507"></a>
516 <span class="sourceLineNo">508</span> String[] args = cmdline == null ? null : cmdline.getArgs();<a name="line.508"></a>
517 <span class="sourceLineNo">509</span> if (args != null &amp;&amp; args.length &gt; 2) {<a name="line.509"></a>
518 <span class="sourceLineNo">510</span> System.err.println("ERROR: wrong number of arguments: " + args.length);<a name="line.510"></a>
519 <span class="sourceLineNo">511</span> printUsage();<a name="line.511"></a>
520 <span class="sourceLineNo">512</span> throw new IOException(INCORRECT_USAGE);<a name="line.512"></a>
521 <span class="sourceLineNo">513</span> }<a name="line.513"></a>
522 <span class="sourceLineNo">514</span><a name="line.514"></a>
523 <span class="sourceLineNo">515</span> super.execute();<a name="line.515"></a>
524 <span class="sourceLineNo">516</span><a name="line.516"></a>
525 <span class="sourceLineNo">517</span> String backupId = (args == null || args.length &lt;= 1) ? null : args[1];<a name="line.517"></a>
526 <span class="sourceLineNo">518</span> try (final BackupSystemTable sysTable = new BackupSystemTable(conn)) {<a name="line.518"></a>
527 <span class="sourceLineNo">519</span> BackupInfo info = null;<a name="line.519"></a>
528 <span class="sourceLineNo">520</span><a name="line.520"></a>
529 <span class="sourceLineNo">521</span> if (backupId != null) {<a name="line.521"></a>
530 <span class="sourceLineNo">522</span> info = sysTable.readBackupInfo(backupId);<a name="line.522"></a>
531 <span class="sourceLineNo">523</span> } else {<a name="line.523"></a>
532 <span class="sourceLineNo">524</span> List&lt;BackupInfo&gt; infos = sysTable.getBackupInfos(BackupState.RUNNING);<a name="line.524"></a>
533 <span class="sourceLineNo">525</span> if (infos != null &amp;&amp; infos.size() &gt; 0) {<a name="line.525"></a>
534 <span class="sourceLineNo">526</span> info = infos.get(0);<a name="line.526"></a>
535 <span class="sourceLineNo">527</span> backupId = info.getBackupId();<a name="line.527"></a>
536 <span class="sourceLineNo">528</span> System.out.println("Found ongoing session with backupId=" + backupId);<a name="line.528"></a>
537 <span class="sourceLineNo">529</span> }<a name="line.529"></a>
538 <span class="sourceLineNo">530</span> }<a name="line.530"></a>
539 <span class="sourceLineNo">531</span> int progress = info == null ? -1 : info.getProgress();<a name="line.531"></a>
540 <span class="sourceLineNo">532</span> if (progress &lt; 0) {<a name="line.532"></a>
541 <span class="sourceLineNo">533</span> if (backupId != null) {<a name="line.533"></a>
542 <span class="sourceLineNo">534</span> System.out.println(NO_INFO_FOUND + backupId);<a name="line.534"></a>
543 <span class="sourceLineNo">535</span> } else {<a name="line.535"></a>
544 <span class="sourceLineNo">536</span> System.err.println(NO_ACTIVE_SESSION_FOUND);<a name="line.536"></a>
545 <span class="sourceLineNo">537</span> }<a name="line.537"></a>
546 <span class="sourceLineNo">538</span> } else {<a name="line.538"></a>
547 <span class="sourceLineNo">539</span> System.out.println(backupId + " progress=" + progress + "%");<a name="line.539"></a>
548 <span class="sourceLineNo">540</span> }<a name="line.540"></a>
549 <span class="sourceLineNo">541</span> }<a name="line.541"></a>
550 <span class="sourceLineNo">542</span> }<a name="line.542"></a>
551 <span class="sourceLineNo">543</span><a name="line.543"></a>
552 <span class="sourceLineNo">544</span> @Override<a name="line.544"></a>
553 <span class="sourceLineNo">545</span> protected void printUsage() {<a name="line.545"></a>
554 <span class="sourceLineNo">546</span> System.out.println(PROGRESS_CMD_USAGE);<a name="line.546"></a>
555 <span class="sourceLineNo">547</span> }<a name="line.547"></a>
556 <span class="sourceLineNo">548</span> }<a name="line.548"></a>
557 <span class="sourceLineNo">549</span><a name="line.549"></a>
558 <span class="sourceLineNo">550</span> public static class DeleteCommand extends Command {<a name="line.550"></a>
559 <span class="sourceLineNo">551</span> DeleteCommand(Configuration conf, CommandLine cmdline) {<a name="line.551"></a>
560 <span class="sourceLineNo">552</span> super(conf);<a name="line.552"></a>
561 <span class="sourceLineNo">553</span> this.cmdline = cmdline;<a name="line.553"></a>
562 <span class="sourceLineNo">554</span> }<a name="line.554"></a>
563 <span class="sourceLineNo">555</span><a name="line.555"></a>
564 <span class="sourceLineNo">556</span> @Override<a name="line.556"></a>
565 <span class="sourceLineNo">557</span> protected boolean requiresNoActiveSession() {<a name="line.557"></a>
566 <span class="sourceLineNo">558</span> return true;<a name="line.558"></a>
567 <span class="sourceLineNo">559</span> }<a name="line.559"></a>
568 <span class="sourceLineNo">560</span><a name="line.560"></a>
569 <span class="sourceLineNo">561</span> @Override<a name="line.561"></a>
570 <span class="sourceLineNo">562</span> public void execute() throws IOException {<a name="line.562"></a>
571 <span class="sourceLineNo">563</span> if (cmdline == null || cmdline.getArgs() == null || cmdline.getArgs().length &lt; 2) {<a name="line.563"></a>
572 <span class="sourceLineNo">564</span> printUsage();<a name="line.564"></a>
573 <span class="sourceLineNo">565</span> throw new IOException(INCORRECT_USAGE);<a name="line.565"></a>
574 <span class="sourceLineNo">566</span> }<a name="line.566"></a>
575 <span class="sourceLineNo">567</span><a name="line.567"></a>
576 <span class="sourceLineNo">568</span> super.execute();<a name="line.568"></a>
577 <span class="sourceLineNo">569</span><a name="line.569"></a>
578 <span class="sourceLineNo">570</span> String[] args = cmdline.getArgs();<a name="line.570"></a>
579 <span class="sourceLineNo">571</span> String[] backupIds = new String[args.length - 1];<a name="line.571"></a>
580 <span class="sourceLineNo">572</span> System.arraycopy(args, 1, backupIds, 0, backupIds.length);<a name="line.572"></a>
581 <span class="sourceLineNo">573</span> try (BackupAdminImpl admin = new BackupAdminImpl(conn)) {<a name="line.573"></a>
582 <span class="sourceLineNo">574</span> int deleted = admin.deleteBackups(backupIds);<a name="line.574"></a>
583 <span class="sourceLineNo">575</span> System.out.println("Deleted " + deleted + " backups. Total requested: " + (args.length -1));<a name="line.575"></a>
584 <span class="sourceLineNo">576</span> } catch (IOException e) {<a name="line.576"></a>
585 <span class="sourceLineNo">577</span> System.err.println("Delete command FAILED. Please run backup repair tool to restore backup "<a name="line.577"></a>
586 <span class="sourceLineNo">578</span> + "system integrity");<a name="line.578"></a>
587 <span class="sourceLineNo">579</span> throw e;<a name="line.579"></a>
588 <span class="sourceLineNo">580</span> }<a name="line.580"></a>
589 <span class="sourceLineNo">581</span> }<a name="line.581"></a>
590 <span class="sourceLineNo">582</span><a name="line.582"></a>
591 <span class="sourceLineNo">583</span> @Override<a name="line.583"></a>
592 <span class="sourceLineNo">584</span> protected void printUsage() {<a name="line.584"></a>
593 <span class="sourceLineNo">585</span> System.out.println(DELETE_CMD_USAGE);<a name="line.585"></a>
594 <span class="sourceLineNo">586</span> }<a name="line.586"></a>
595 <span class="sourceLineNo">587</span> }<a name="line.587"></a>
596 <span class="sourceLineNo">588</span><a name="line.588"></a>
597 <span class="sourceLineNo">589</span> public static class RepairCommand extends Command {<a name="line.589"></a>
598 <span class="sourceLineNo">590</span> RepairCommand(Configuration conf, CommandLine cmdline) {<a name="line.590"></a>
599 <span class="sourceLineNo">591</span> super(conf);<a name="line.591"></a>
600 <span class="sourceLineNo">592</span> this.cmdline = cmdline;<a name="line.592"></a>
601 <span class="sourceLineNo">593</span> }<a name="line.593"></a>
602 <span class="sourceLineNo">594</span><a name="line.594"></a>
603 <span class="sourceLineNo">595</span> @Override<a name="line.595"></a>
604 <span class="sourceLineNo">596</span> public void execute() throws IOException {<a name="line.596"></a>
605 <span class="sourceLineNo">597</span> super.execute();<a name="line.597"></a>
606 <span class="sourceLineNo">598</span><a name="line.598"></a>
607 <span class="sourceLineNo">599</span> String[] args = cmdline == null ? null : cmdline.getArgs();<a name="line.599"></a>
608 <span class="sourceLineNo">600</span> if (args != null &amp;&amp; args.length &gt; 1) {<a name="line.600"></a>
609 <span class="sourceLineNo">601</span> System.err.println("ERROR: wrong number of arguments: " + args.length);<a name="line.601"></a>
610 <span class="sourceLineNo">602</span> printUsage();<a name="line.602"></a>
611 <span class="sourceLineNo">603</span> throw new IOException(INCORRECT_USAGE);<a name="line.603"></a>
612 <span class="sourceLineNo">604</span> }<a name="line.604"></a>
613 <span class="sourceLineNo">605</span><a name="line.605"></a>
614 <span class="sourceLineNo">606</span> Configuration conf = getConf() != null ? getConf() : HBaseConfiguration.create();<a name="line.606"></a>
615 <span class="sourceLineNo">607</span> try (final Connection conn = ConnectionFactory.createConnection(conf);<a name="line.607"></a>
616 <span class="sourceLineNo">608</span> final BackupSystemTable sysTable = new BackupSystemTable(conn)) {<a name="line.608"></a>
617 <span class="sourceLineNo">609</span> // Failed backup<a name="line.609"></a>
618 <span class="sourceLineNo">610</span> BackupInfo backupInfo;<a name="line.610"></a>
619 <span class="sourceLineNo">611</span> List&lt;BackupInfo&gt; list = sysTable.getBackupInfos(BackupState.RUNNING);<a name="line.611"></a>
620 <span class="sourceLineNo">612</span> if (list.size() == 0) {<a name="line.612"></a>
621 <span class="sourceLineNo">613</span> // No failed sessions found<a name="line.613"></a>
622 <span class="sourceLineNo">614</span> System.out.println("REPAIR status: no failed sessions found."<a name="line.614"></a>
623 <span class="sourceLineNo">615</span> + " Checking failed delete backup operation ...");<a name="line.615"></a>
624 <span class="sourceLineNo">616</span> repairFailedBackupDeletionIfAny(conn, sysTable);<a name="line.616"></a>
625 <span class="sourceLineNo">617</span> repairFailedBackupMergeIfAny(conn, sysTable);<a name="line.617"></a>
626 <span class="sourceLineNo">618</span> return;<a name="line.618"></a>
627 <span class="sourceLineNo">619</span> }<a name="line.619"></a>
628 <span class="sourceLineNo">620</span> backupInfo = list.get(0);<a name="line.620"></a>
629 <span class="sourceLineNo">621</span> // If this is a cancel exception, then we've already cleaned.<a name="line.621"></a>
630 <span class="sourceLineNo">622</span> // set the failure timestamp of the overall backup<a name="line.622"></a>
631 <span class="sourceLineNo">623</span> backupInfo.setCompleteTs(EnvironmentEdgeManager.currentTime());<a name="line.623"></a>
632 <span class="sourceLineNo">624</span> // set failure message<a name="line.624"></a>
633 <span class="sourceLineNo">625</span> backupInfo.setFailedMsg("REPAIR status: repaired after failure:\n" + backupInfo);<a name="line.625"></a>
634 <span class="sourceLineNo">626</span> // set overall backup status: failed<a name="line.626"></a>
635 <span class="sourceLineNo">627</span> backupInfo.setState(BackupState.FAILED);<a name="line.627"></a>
636 <span class="sourceLineNo">628</span> // compose the backup failed data<a name="line.628"></a>
637 <span class="sourceLineNo">629</span> String backupFailedData =<a name="line.629"></a>
638 <span class="sourceLineNo">630</span> "BackupId=" + backupInfo.getBackupId() + ",startts=" + backupInfo.getStartTs()<a name="line.630"></a>
639 <span class="sourceLineNo">631</span> + ",failedts=" + backupInfo.getCompleteTs() + ",failedphase="<a name="line.631"></a>
640 <span class="sourceLineNo">632</span> + backupInfo.getPhase() + ",failedmessage=" + backupInfo.getFailedMsg();<a name="line.632"></a>
641 <span class="sourceLineNo">633</span> System.out.println(backupFailedData);<a name="line.633"></a>
642 <span class="sourceLineNo">634</span> TableBackupClient.cleanupAndRestoreBackupSystem(conn, backupInfo, conf);<a name="line.634"></a>
643 <span class="sourceLineNo">635</span> // If backup session is updated to FAILED state - means we<a name="line.635"></a>
644 <span class="sourceLineNo">636</span> // processed recovery already.<a name="line.636"></a>
645 <span class="sourceLineNo">637</span> sysTable.updateBackupInfo(backupInfo);<a name="line.637"></a>
646 <span class="sourceLineNo">638</span> sysTable.finishBackupExclusiveOperation();<a name="line.638"></a>
647 <span class="sourceLineNo">639</span> System.out.println("REPAIR status: finished repair failed session:\n " + backupInfo);<a name="line.639"></a>
648 <span class="sourceLineNo">640</span> }<a name="line.640"></a>
649 <span class="sourceLineNo">641</span> }<a name="line.641"></a>
650 <span class="sourceLineNo">642</span><a name="line.642"></a>
651 <span class="sourceLineNo">643</span> private void repairFailedBackupDeletionIfAny(Connection conn, BackupSystemTable sysTable)<a name="line.643"></a>
652 <span class="sourceLineNo">644</span> throws IOException {<a name="line.644"></a>
653 <span class="sourceLineNo">645</span> String[] backupIds = sysTable.getListOfBackupIdsFromDeleteOperation();<a name="line.645"></a>
654 <span class="sourceLineNo">646</span> if (backupIds == null || backupIds.length == 0) {<a name="line.646"></a>
655 <span class="sourceLineNo">647</span> System.out.println("No failed backup DELETE operation found");<a name="line.647"></a>
656 <span class="sourceLineNo">648</span> // Delete backup table snapshot if exists<a name="line.648"></a>
657 <span class="sourceLineNo">649</span> BackupSystemTable.deleteSnapshot(conn);<a name="line.649"></a>
658 <span class="sourceLineNo">650</span> return;<a name="line.650"></a>
659 <span class="sourceLineNo">651</span> }<a name="line.651"></a>
660 <span class="sourceLineNo">652</span> System.out.println("Found failed DELETE operation for: " + StringUtils.join(backupIds));<a name="line.652"></a>
661 <span class="sourceLineNo">653</span> System.out.println("Running DELETE again ...");<a name="line.653"></a>
662 <span class="sourceLineNo">654</span> // Restore table from snapshot<a name="line.654"></a>
663 <span class="sourceLineNo">655</span> BackupSystemTable.restoreFromSnapshot(conn);<a name="line.655"></a>
664 <span class="sourceLineNo">656</span> // Finish previous failed session<a name="line.656"></a>
665 <span class="sourceLineNo">657</span> sysTable.finishBackupExclusiveOperation();<a name="line.657"></a>
666 <span class="sourceLineNo">658</span> try (BackupAdmin admin = new BackupAdminImpl(conn)) {<a name="line.658"></a>
667 <span class="sourceLineNo">659</span> admin.deleteBackups(backupIds);<a name="line.659"></a>
668 <span class="sourceLineNo">660</span> }<a name="line.660"></a>
669 <span class="sourceLineNo">661</span> System.out.println("DELETE operation finished OK: " + StringUtils.join(backupIds));<a name="line.661"></a>
670 <span class="sourceLineNo">662</span> }<a name="line.662"></a>
671 <span class="sourceLineNo">663</span><a name="line.663"></a>
672 <span class="sourceLineNo">664</span> public static void repairFailedBackupMergeIfAny(Connection conn, BackupSystemTable sysTable)<a name="line.664"></a>
673 <span class="sourceLineNo">665</span> throws IOException {<a name="line.665"></a>
674 <span class="sourceLineNo">666</span><a name="line.666"></a>
675 <span class="sourceLineNo">667</span> String[] backupIds = sysTable.getListOfBackupIdsFromMergeOperation();<a name="line.667"></a>
676 <span class="sourceLineNo">668</span> if (backupIds == null || backupIds.length == 0) {<a name="line.668"></a>
677 <span class="sourceLineNo">669</span> System.out.println("No failed backup MERGE operation found");<a name="line.669"></a>
678 <span class="sourceLineNo">670</span> // Delete backup table snapshot if exists<a name="line.670"></a>
679 <span class="sourceLineNo">671</span> BackupSystemTable.deleteSnapshot(conn);<a name="line.671"></a>
680 <span class="sourceLineNo">672</span> return;<a name="line.672"></a>
681 <span class="sourceLineNo">673</span> }<a name="line.673"></a>
682 <span class="sourceLineNo">674</span> System.out.println("Found failed MERGE operation for: " + StringUtils.join(backupIds));<a name="line.674"></a>
683 <span class="sourceLineNo">675</span> // Check if backup .tmp exists<a name="line.675"></a>
684 <span class="sourceLineNo">676</span> BackupInfo bInfo = sysTable.readBackupInfo(backupIds[0]);<a name="line.676"></a>
685 <span class="sourceLineNo">677</span> String backupRoot = bInfo.getBackupRootDir();<a name="line.677"></a>
686 <span class="sourceLineNo">678</span> FileSystem fs = FileSystem.get(new Path(backupRoot).toUri(), new Configuration());<a name="line.678"></a>
687 <span class="sourceLineNo">679</span> String backupId = BackupUtils.findMostRecentBackupId(backupIds);<a name="line.679"></a>
688 <span class="sourceLineNo">680</span> Path tmpPath = HBackupFileSystem.getBackupTmpDirPathForBackupId(backupRoot, backupId);<a name="line.680"></a>
689 <span class="sourceLineNo">681</span> if (fs.exists(tmpPath)) {<a name="line.681"></a>
690 <span class="sourceLineNo">682</span> // Move data back<a name="line.682"></a>
691 <span class="sourceLineNo">683</span> Path destPath = HBackupFileSystem.getBackupPath(backupRoot, backupId);<a name="line.683"></a>
692 <span class="sourceLineNo">684</span> if (!fs.delete(destPath, true)) {<a name="line.684"></a>
693 <span class="sourceLineNo">685</span> System.out.println("Failed to delete " + destPath);<a name="line.685"></a>
694 <span class="sourceLineNo">686</span> }<a name="line.686"></a>
695 <span class="sourceLineNo">687</span> boolean res = fs.rename(tmpPath, destPath);<a name="line.687"></a>
696 <span class="sourceLineNo">688</span> if (!res) {<a name="line.688"></a>
697 <span class="sourceLineNo">689</span> throw new IOException("MERGE repair: failed to rename from "+ tmpPath+" to "+ destPath);<a name="line.689"></a>
698 <span class="sourceLineNo">690</span> }<a name="line.690"></a>
699 <span class="sourceLineNo">691</span> System.out.println("MERGE repair: renamed from "+ tmpPath+" to "+ destPath+" res="+ res);<a name="line.691"></a>
700 <span class="sourceLineNo">692</span> } else {<a name="line.692"></a>
701 <span class="sourceLineNo">693</span> checkRemoveBackupImages(fs, backupRoot, backupIds);<a name="line.693"></a>
702 <span class="sourceLineNo">694</span> }<a name="line.694"></a>
703 <span class="sourceLineNo">695</span> // Restore table from snapshot<a name="line.695"></a>
704 <span class="sourceLineNo">696</span> BackupSystemTable.restoreFromSnapshot(conn);<a name="line.696"></a>
705 <span class="sourceLineNo">697</span> // Unlock backup system<a name="line.697"></a>
706 <span class="sourceLineNo">698</span> sysTable.finishBackupExclusiveOperation();<a name="line.698"></a>
707 <span class="sourceLineNo">699</span> // Finish previous failed session<a name="line.699"></a>
708 <span class="sourceLineNo">700</span> sysTable.finishMergeOperation();<a name="line.700"></a>
709 <span class="sourceLineNo">701</span><a name="line.701"></a>
710 <span class="sourceLineNo">702</span> System.out.println("MERGE repair operation finished OK: " + StringUtils.join(backupIds));<a name="line.702"></a>
711 <span class="sourceLineNo">703</span> }<a name="line.703"></a>
712 <span class="sourceLineNo">704</span><a name="line.704"></a>
713 <span class="sourceLineNo">705</span> private static void checkRemoveBackupImages(FileSystem fs, String backupRoot,<a name="line.705"></a>
714 <span class="sourceLineNo">706</span> String[] backupIds) throws IOException {<a name="line.706"></a>
715 <span class="sourceLineNo">707</span> String mergedBackupId = BackupUtils.findMostRecentBackupId(backupIds);<a name="line.707"></a>
716 <span class="sourceLineNo">708</span> for (String backupId: backupIds) {<a name="line.708"></a>
717 <span class="sourceLineNo">709</span> if (backupId.equals(mergedBackupId)) {<a name="line.709"></a>
718 <span class="sourceLineNo">710</span> continue;<a name="line.710"></a>
719 <span class="sourceLineNo">711</span> }<a name="line.711"></a>
720 <span class="sourceLineNo">712</span> Path path = HBackupFileSystem.getBackupPath(backupRoot, backupId);<a name="line.712"></a>
721 <span class="sourceLineNo">713</span> if (fs.exists(path)) {<a name="line.713"></a>
722 <span class="sourceLineNo">714</span> if (!fs.delete(path, true)) {<a name="line.714"></a>
723 <span class="sourceLineNo">715</span> System.out.println("MERGE repair removing: "+ path +" - FAILED");<a name="line.715"></a>
724 <span class="sourceLineNo">716</span> } else {<a name="line.716"></a>
725 <span class="sourceLineNo">717</span> System.out.println("MERGE repair removing: "+ path +" - OK");<a name="line.717"></a>
726 <span class="sourceLineNo">718</span> }<a name="line.718"></a>
727 <span class="sourceLineNo">719</span> }<a name="line.719"></a>
728 <span class="sourceLineNo">720</span> }<a name="line.720"></a>
729 <span class="sourceLineNo">721</span> }<a name="line.721"></a>
730 <span class="sourceLineNo">722</span><a name="line.722"></a>
731 <span class="sourceLineNo">723</span> @Override<a name="line.723"></a>
732 <span class="sourceLineNo">724</span> protected void printUsage() {<a name="line.724"></a>
733 <span class="sourceLineNo">725</span> System.out.println(REPAIR_CMD_USAGE);<a name="line.725"></a>
734 <span class="sourceLineNo">726</span> }<a name="line.726"></a>
735 <span class="sourceLineNo">727</span> }<a name="line.727"></a>
736 <span class="sourceLineNo">728</span><a name="line.728"></a>
737 <span class="sourceLineNo">729</span> public static class MergeCommand extends Command {<a name="line.729"></a>
738 <span class="sourceLineNo">730</span> MergeCommand(Configuration conf, CommandLine cmdline) {<a name="line.730"></a>
739 <span class="sourceLineNo">731</span> super(conf);<a name="line.731"></a>
740 <span class="sourceLineNo">732</span> this.cmdline = cmdline;<a name="line.732"></a>
741 <span class="sourceLineNo">733</span> }<a name="line.733"></a>
742 <span class="sourceLineNo">734</span><a name="line.734"></a>
743 <span class="sourceLineNo">735</span> @Override<a name="line.735"></a>
744 <span class="sourceLineNo">736</span> protected boolean requiresNoActiveSession() {<a name="line.736"></a>
745 <span class="sourceLineNo">737</span> return true;<a name="line.737"></a>
746 <span class="sourceLineNo">738</span> }<a name="line.738"></a>
747 <span class="sourceLineNo">739</span><a name="line.739"></a>
748 <span class="sourceLineNo">740</span> @Override<a name="line.740"></a>
749 <span class="sourceLineNo">741</span> protected boolean requiresConsistentState() {<a name="line.741"></a>
750 <span class="sourceLineNo">742</span> return true;<a name="line.742"></a>
751 <span class="sourceLineNo">743</span> }<a name="line.743"></a>
752 <span class="sourceLineNo">744</span><a name="line.744"></a>
753 <span class="sourceLineNo">745</span> @Override<a name="line.745"></a>
754 <span class="sourceLineNo">746</span> public void execute() throws IOException {<a name="line.746"></a>
755 <span class="sourceLineNo">747</span> super.execute();<a name="line.747"></a>
756 <span class="sourceLineNo">748</span><a name="line.748"></a>
757 <span class="sourceLineNo">749</span> String[] args = cmdline == null ? null : cmdline.getArgs();<a name="line.749"></a>
758 <span class="sourceLineNo">750</span> if (args == null || (args.length != 2)) {<a name="line.750"></a>
759 <span class="sourceLineNo">751</span> System.err.println("ERROR: wrong number of arguments: "<a name="line.751"></a>
760 <span class="sourceLineNo">752</span> + (args == null ? null : args.length));<a name="line.752"></a>
761 <span class="sourceLineNo">753</span> printUsage();<a name="line.753"></a>
762 <span class="sourceLineNo">754</span> throw new IOException(INCORRECT_USAGE);<a name="line.754"></a>
763 <span class="sourceLineNo">755</span> }<a name="line.755"></a>
764 <span class="sourceLineNo">756</span><a name="line.756"></a>
765 <span class="sourceLineNo">757</span> String[] backupIds = args[1].split(",");<a name="line.757"></a>
766 <span class="sourceLineNo">758</span> if (backupIds.length &lt; 2) {<a name="line.758"></a>
767 <span class="sourceLineNo">759</span> String msg = "ERROR: can not merge a single backup image. "+<a name="line.759"></a>
768 <span class="sourceLineNo">760</span> "Number of images must be greater than 1.";<a name="line.760"></a>
769 <span class="sourceLineNo">761</span> System.err.println(msg);<a name="line.761"></a>
770 <span class="sourceLineNo">762</span> throw new IOException(msg);<a name="line.762"></a>
771 <span class="sourceLineNo">763</span><a name="line.763"></a>
772 <span class="sourceLineNo">764</span> }<a name="line.764"></a>
773 <span class="sourceLineNo">765</span> Configuration conf = getConf() != null ? getConf() : HBaseConfiguration.create();<a name="line.765"></a>
774 <span class="sourceLineNo">766</span> try (final Connection conn = ConnectionFactory.createConnection(conf);<a name="line.766"></a>
775 <span class="sourceLineNo">767</span> final BackupAdminImpl admin = new BackupAdminImpl(conn)) {<a name="line.767"></a>
776 <span class="sourceLineNo">768</span> admin.mergeBackups(backupIds);<a name="line.768"></a>
777 <span class="sourceLineNo">769</span> }<a name="line.769"></a>
778 <span class="sourceLineNo">770</span> }<a name="line.770"></a>
779 <span class="sourceLineNo">771</span><a name="line.771"></a>
780 <span class="sourceLineNo">772</span> @Override<a name="line.772"></a>
781 <span class="sourceLineNo">773</span> protected void printUsage() {<a name="line.773"></a>
782 <span class="sourceLineNo">774</span> System.out.println(MERGE_CMD_USAGE);<a name="line.774"></a>
783 <span class="sourceLineNo">775</span> }<a name="line.775"></a>
784 <span class="sourceLineNo">776</span> }<a name="line.776"></a>
785 <span class="sourceLineNo">777</span><a name="line.777"></a>
786 <span class="sourceLineNo">778</span> public static class HistoryCommand extends Command {<a name="line.778"></a>
787 <span class="sourceLineNo">779</span> private final static int DEFAULT_HISTORY_LENGTH = 10;<a name="line.779"></a>
788 <span class="sourceLineNo">780</span><a name="line.780"></a>
789 <span class="sourceLineNo">781</span> HistoryCommand(Configuration conf, CommandLine cmdline) {<a name="line.781"></a>
790 <span class="sourceLineNo">782</span> super(conf);<a name="line.782"></a>
791 <span class="sourceLineNo">783</span> this.cmdline = cmdline;<a name="line.783"></a>
792 <span class="sourceLineNo">784</span> }<a name="line.784"></a>
793 <span class="sourceLineNo">785</span><a name="line.785"></a>
794 <span class="sourceLineNo">786</span> @Override<a name="line.786"></a>
795 <span class="sourceLineNo">787</span> public void execute() throws IOException {<a name="line.787"></a>
796 <span class="sourceLineNo">788</span> int n = parseHistoryLength();<a name="line.788"></a>
797 <span class="sourceLineNo">789</span> final TableName tableName = getTableName();<a name="line.789"></a>
798 <span class="sourceLineNo">790</span> final String setName = getTableSetName();<a name="line.790"></a>
799 <span class="sourceLineNo">791</span> BackupInfo.Filter tableNameFilter = new BackupInfo.Filter() {<a name="line.791"></a>
800 <span class="sourceLineNo">792</span> @Override<a name="line.792"></a>
801 <span class="sourceLineNo">793</span> public boolean apply(BackupInfo info) {<a name="line.793"></a>
802 <span class="sourceLineNo">794</span> if (tableName == null) {<a name="line.794"></a>
803 <span class="sourceLineNo">795</span> return true;<a name="line.795"></a>
804 <span class="sourceLineNo">796</span> }<a name="line.796"></a>
805 <span class="sourceLineNo">797</span><a name="line.797"></a>
806 <span class="sourceLineNo">798</span> List&lt;TableName&gt; names = info.getTableNames();<a name="line.798"></a>
807 <span class="sourceLineNo">799</span> return names.contains(tableName);<a name="line.799"></a>
808 <span class="sourceLineNo">800</span> }<a name="line.800"></a>
809 <span class="sourceLineNo">801</span> };<a name="line.801"></a>
810 <span class="sourceLineNo">802</span> BackupInfo.Filter tableSetFilter = new BackupInfo.Filter() {<a name="line.802"></a>
811 <span class="sourceLineNo">803</span> @Override<a name="line.803"></a>
812 <span class="sourceLineNo">804</span> public boolean apply(BackupInfo info) {<a name="line.804"></a>
813 <span class="sourceLineNo">805</span> if (setName == null) {<a name="line.805"></a>
814 <span class="sourceLineNo">806</span> return true;<a name="line.806"></a>
815 <span class="sourceLineNo">807</span> }<a name="line.807"></a>
816 <span class="sourceLineNo">808</span><a name="line.808"></a>
817 <span class="sourceLineNo">809</span> String backupId = info.getBackupId();<a name="line.809"></a>
818 <span class="sourceLineNo">810</span> return backupId.startsWith(setName);<a name="line.810"></a>
819 <span class="sourceLineNo">811</span> }<a name="line.811"></a>
820 <span class="sourceLineNo">812</span> };<a name="line.812"></a>
821 <span class="sourceLineNo">813</span> Path backupRootPath = getBackupRootPath();<a name="line.813"></a>
822 <span class="sourceLineNo">814</span> List&lt;BackupInfo&gt; history;<a name="line.814"></a>
823 <span class="sourceLineNo">815</span> if (backupRootPath == null) {<a name="line.815"></a>
824 <span class="sourceLineNo">816</span> // Load from backup system table<a name="line.816"></a>
825 <span class="sourceLineNo">817</span> super.execute();<a name="line.817"></a>
826 <span class="sourceLineNo">818</span> try (final BackupSystemTable sysTable = new BackupSystemTable(conn)) {<a name="line.818"></a>
827 <span class="sourceLineNo">819</span> history = sysTable.getBackupHistory(n, tableNameFilter, tableSetFilter);<a name="line.819"></a>
828 <span class="sourceLineNo">820</span> }<a name="line.820"></a>
829 <span class="sourceLineNo">821</span> } else {<a name="line.821"></a>
830 <span class="sourceLineNo">822</span> // load from backup FS<a name="line.822"></a>
831 <span class="sourceLineNo">823</span> history =<a name="line.823"></a>
832 <span class="sourceLineNo">824</span> BackupUtils.getHistory(getConf(), n, backupRootPath, tableNameFilter, tableSetFilter);<a name="line.824"></a>
833 <span class="sourceLineNo">825</span> }<a name="line.825"></a>
834 <span class="sourceLineNo">826</span> for (BackupInfo info : history) {<a name="line.826"></a>
835 <span class="sourceLineNo">827</span> System.out.println(info.getShortDescription());<a name="line.827"></a>
836 <span class="sourceLineNo">828</span> }<a name="line.828"></a>
837 <span class="sourceLineNo">829</span> }<a name="line.829"></a>
838 <span class="sourceLineNo">830</span><a name="line.830"></a>
839 <span class="sourceLineNo">831</span> private Path getBackupRootPath() throws IOException {<a name="line.831"></a>
840 <span class="sourceLineNo">832</span> String value = null;<a name="line.832"></a>
841 <span class="sourceLineNo">833</span> try {<a name="line.833"></a>
842 <span class="sourceLineNo">834</span> value = cmdline.getOptionValue(OPTION_PATH);<a name="line.834"></a>
843 <span class="sourceLineNo">835</span><a name="line.835"></a>
844 <span class="sourceLineNo">836</span> if (value == null) {<a name="line.836"></a>
845 <span class="sourceLineNo">837</span> return null;<a name="line.837"></a>
846 <span class="sourceLineNo">838</span> }<a name="line.838"></a>
847 <span class="sourceLineNo">839</span><a name="line.839"></a>
848 <span class="sourceLineNo">840</span> return new Path(value);<a name="line.840"></a>
849 <span class="sourceLineNo">841</span> } catch (IllegalArgumentException e) {<a name="line.841"></a>
850 <span class="sourceLineNo">842</span> System.out.println("ERROR: Illegal argument for backup root path: " + value);<a name="line.842"></a>
851 <span class="sourceLineNo">843</span> printUsage();<a name="line.843"></a>
852 <span class="sourceLineNo">844</span> throw new IOException(INCORRECT_USAGE);<a name="line.844"></a>
853 <span class="sourceLineNo">845</span> }<a name="line.845"></a>
854 <span class="sourceLineNo">846</span> }<a name="line.846"></a>
855 <span class="sourceLineNo">847</span><a name="line.847"></a>
856 <span class="sourceLineNo">848</span> private TableName getTableName() throws IOException {<a name="line.848"></a>
857 <span class="sourceLineNo">849</span> String value = cmdline.getOptionValue(OPTION_TABLE);<a name="line.849"></a>
858 <span class="sourceLineNo">850</span><a name="line.850"></a>
859 <span class="sourceLineNo">851</span> if (value == null) {<a name="line.851"></a>
860 <span class="sourceLineNo">852</span> return null;<a name="line.852"></a>
861 <span class="sourceLineNo">853</span> }<a name="line.853"></a>
862 <span class="sourceLineNo">854</span><a name="line.854"></a>
863 <span class="sourceLineNo">855</span> try {<a name="line.855"></a>
864 <span class="sourceLineNo">856</span> return TableName.valueOf(value);<a name="line.856"></a>
865 <span class="sourceLineNo">857</span> } catch (IllegalArgumentException e) {<a name="line.857"></a>
866 <span class="sourceLineNo">858</span> System.out.println("Illegal argument for table name: " + value);<a name="line.858"></a>
867 <span class="sourceLineNo">859</span> printUsage();<a name="line.859"></a>
868 <span class="sourceLineNo">860</span> throw new IOException(INCORRECT_USAGE);<a name="line.860"></a>
869 <span class="sourceLineNo">861</span> }<a name="line.861"></a>
870 <span class="sourceLineNo">862</span> }<a name="line.862"></a>
871 <span class="sourceLineNo">863</span><a name="line.863"></a>
872 <span class="sourceLineNo">864</span> private String getTableSetName() {<a name="line.864"></a>
873 <span class="sourceLineNo">865</span> return cmdline.getOptionValue(OPTION_SET);<a name="line.865"></a>
874 <span class="sourceLineNo">866</span> }<a name="line.866"></a>
875 <span class="sourceLineNo">867</span><a name="line.867"></a>
876 <span class="sourceLineNo">868</span> private int parseHistoryLength() throws IOException {<a name="line.868"></a>
877 <span class="sourceLineNo">869</span> String value = cmdline.getOptionValue(OPTION_RECORD_NUMBER);<a name="line.869"></a>
878 <span class="sourceLineNo">870</span> try {<a name="line.870"></a>
879 <span class="sourceLineNo">871</span> if (value == null) {<a name="line.871"></a>
880 <span class="sourceLineNo">872</span> return DEFAULT_HISTORY_LENGTH;<a name="line.872"></a>
881 <span class="sourceLineNo">873</span> }<a name="line.873"></a>
882 <span class="sourceLineNo">874</span><a name="line.874"></a>
883 <span class="sourceLineNo">875</span> return Integer.parseInt(value);<a name="line.875"></a>
884 <span class="sourceLineNo">876</span> } catch (NumberFormatException e) {<a name="line.876"></a>
885 <span class="sourceLineNo">877</span> System.out.println("Illegal argument for history length: " + value);<a name="line.877"></a>
886 <span class="sourceLineNo">878</span> printUsage();<a name="line.878"></a>
887 <span class="sourceLineNo">879</span> throw new IOException(INCORRECT_USAGE);<a name="line.879"></a>
888 <span class="sourceLineNo">880</span> }<a name="line.880"></a>
889 <span class="sourceLineNo">881</span> }<a name="line.881"></a>
890 <span class="sourceLineNo">882</span><a name="line.882"></a>
891 <span class="sourceLineNo">883</span> @Override<a name="line.883"></a>
892 <span class="sourceLineNo">884</span> protected void printUsage() {<a name="line.884"></a>
893 <span class="sourceLineNo">885</span> System.out.println(HISTORY_CMD_USAGE);<a name="line.885"></a>
894 <span class="sourceLineNo">886</span> Options options = new Options();<a name="line.886"></a>
895 <span class="sourceLineNo">887</span> options.addOption(OPTION_RECORD_NUMBER, true, OPTION_RECORD_NUMBER_DESC);<a name="line.887"></a>
896 <span class="sourceLineNo">888</span> options.addOption(OPTION_PATH, true, OPTION_PATH_DESC);<a name="line.888"></a>
897 <span class="sourceLineNo">889</span> options.addOption(OPTION_TABLE, true, OPTION_TABLE_DESC);<a name="line.889"></a>
898 <span class="sourceLineNo">890</span> options.addOption(OPTION_SET, true, OPTION_SET_DESC);<a name="line.890"></a>
899 <span class="sourceLineNo">891</span><a name="line.891"></a>
900 <span class="sourceLineNo">892</span> HelpFormatter helpFormatter = new HelpFormatter();<a name="line.892"></a>
901 <span class="sourceLineNo">893</span> helpFormatter.setLeftPadding(2);<a name="line.893"></a>
902 <span class="sourceLineNo">894</span> helpFormatter.setDescPadding(8);<a name="line.894"></a>
903 <span class="sourceLineNo">895</span> helpFormatter.setWidth(100);<a name="line.895"></a>
904 <span class="sourceLineNo">896</span> helpFormatter.setSyntaxPrefix("Options:");<a name="line.896"></a>
905 <span class="sourceLineNo">897</span> helpFormatter.printHelp(" ", null, options, USAGE_FOOTER);<a name="line.897"></a>
906 <span class="sourceLineNo">898</span> }<a name="line.898"></a>
907 <span class="sourceLineNo">899</span> }<a name="line.899"></a>
908 <span class="sourceLineNo">900</span><a name="line.900"></a>
909 <span class="sourceLineNo">901</span> public static class BackupSetCommand extends Command {<a name="line.901"></a>
910 <span class="sourceLineNo">902</span> private final static String SET_ADD_CMD = "add";<a name="line.902"></a>
911 <span class="sourceLineNo">903</span> private final static String SET_REMOVE_CMD = "remove";<a name="line.903"></a>
912 <span class="sourceLineNo">904</span> private final static String SET_DELETE_CMD = "delete";<a name="line.904"></a>
913 <span class="sourceLineNo">905</span> private final static String SET_DESCRIBE_CMD = "describe";<a name="line.905"></a>
914 <span class="sourceLineNo">906</span> private final static String SET_LIST_CMD = "list";<a name="line.906"></a>
915 <span class="sourceLineNo">907</span><a name="line.907"></a>
916 <span class="sourceLineNo">908</span> BackupSetCommand(Configuration conf, CommandLine cmdline) {<a name="line.908"></a>
917 <span class="sourceLineNo">909</span> super(conf);<a name="line.909"></a>
918 <span class="sourceLineNo">910</span> this.cmdline = cmdline;<a name="line.910"></a>
919 <span class="sourceLineNo">911</span> }<a name="line.911"></a>
920 <span class="sourceLineNo">912</span><a name="line.912"></a>
921 <span class="sourceLineNo">913</span> @Override<a name="line.913"></a>
922 <span class="sourceLineNo">914</span> public void execute() throws IOException {<a name="line.914"></a>
923 <span class="sourceLineNo">915</span> // Command-line must have at least one element<a name="line.915"></a>
924 <span class="sourceLineNo">916</span> if (cmdline == null || cmdline.getArgs() == null || cmdline.getArgs().length &lt; 2) {<a name="line.916"></a>
925 <span class="sourceLineNo">917</span> printUsage();<a name="line.917"></a>
926 <span class="sourceLineNo">918</span> throw new IOException(INCORRECT_USAGE);<a name="line.918"></a>
927 <span class="sourceLineNo">919</span> }<a name="line.919"></a>
928 <span class="sourceLineNo">920</span><a name="line.920"></a>
929 <span class="sourceLineNo">921</span> String[] args = cmdline.getArgs();<a name="line.921"></a>
930 <span class="sourceLineNo">922</span> String cmdStr = args[1];<a name="line.922"></a>
931 <span class="sourceLineNo">923</span> BackupCommand cmd = getCommand(cmdStr);<a name="line.923"></a>
932 <span class="sourceLineNo">924</span><a name="line.924"></a>
933 <span class="sourceLineNo">925</span> switch (cmd) {<a name="line.925"></a>
934 <span class="sourceLineNo">926</span> case SET_ADD:<a name="line.926"></a>
935 <span class="sourceLineNo">927</span> processSetAdd(args);<a name="line.927"></a>
936 <span class="sourceLineNo">928</span> break;<a name="line.928"></a>
937 <span class="sourceLineNo">929</span> case SET_REMOVE:<a name="line.929"></a>
938 <span class="sourceLineNo">930</span> processSetRemove(args);<a name="line.930"></a>
939 <span class="sourceLineNo">931</span> break;<a name="line.931"></a>
940 <span class="sourceLineNo">932</span> case SET_DELETE:<a name="line.932"></a>
941 <span class="sourceLineNo">933</span> processSetDelete(args);<a name="line.933"></a>
942 <span class="sourceLineNo">934</span> break;<a name="line.934"></a>
943 <span class="sourceLineNo">935</span> case SET_DESCRIBE:<a name="line.935"></a>
944 <span class="sourceLineNo">936</span> processSetDescribe(args);<a name="line.936"></a>
945 <span class="sourceLineNo">937</span> break;<a name="line.937"></a>
946 <span class="sourceLineNo">938</span> case SET_LIST:<a name="line.938"></a>
947 <span class="sourceLineNo">939</span> processSetList(args);<a name="line.939"></a>
948 <span class="sourceLineNo">940</span> break;<a name="line.940"></a>
949 <span class="sourceLineNo">941</span> default:<a name="line.941"></a>
950 <span class="sourceLineNo">942</span> break;<a name="line.942"></a>
951 <span class="sourceLineNo">943</span> }<a name="line.943"></a>
952 <span class="sourceLineNo">944</span> }<a name="line.944"></a>
953 <span class="sourceLineNo">945</span><a name="line.945"></a>
954 <span class="sourceLineNo">946</span> private void processSetList(String[] args) throws IOException {<a name="line.946"></a>
955 <span class="sourceLineNo">947</span> super.execute();<a name="line.947"></a>
956 <span class="sourceLineNo">948</span><a name="line.948"></a>
957 <span class="sourceLineNo">949</span> // List all backup set names<a name="line.949"></a>
958 <span class="sourceLineNo">950</span> // does not expect any args<a name="line.950"></a>
959 <span class="sourceLineNo">951</span> try (BackupAdminImpl admin = new BackupAdminImpl(conn)) {<a name="line.951"></a>
960 <span class="sourceLineNo">952</span> List&lt;BackupSet&gt; list = admin.listBackupSets();<a name="line.952"></a>
961 <span class="sourceLineNo">953</span> for (BackupSet bs : list) {<a name="line.953"></a>
962 <span class="sourceLineNo">954</span> System.out.println(bs);<a name="line.954"></a>
963 <span class="sourceLineNo">955</span> }<a name="line.955"></a>
964 <span class="sourceLineNo">956</span> }<a name="line.956"></a>
965 <span class="sourceLineNo">957</span> }<a name="line.957"></a>
966 <span class="sourceLineNo">958</span><a name="line.958"></a>
967 <span class="sourceLineNo">959</span> private void processSetDescribe(String[] args) throws IOException {<a name="line.959"></a>
968 <span class="sourceLineNo">960</span> if (args == null || args.length != 3) {<a name="line.960"></a>
969 <span class="sourceLineNo">961</span> printUsage();<a name="line.961"></a>
970 <span class="sourceLineNo">962</span> throw new IOException(INCORRECT_USAGE);<a name="line.962"></a>
971 <span class="sourceLineNo">963</span> }<a name="line.963"></a>
972 <span class="sourceLineNo">964</span> super.execute();<a name="line.964"></a>
973 <span class="sourceLineNo">965</span><a name="line.965"></a>
974 <span class="sourceLineNo">966</span> String setName = args[2];<a name="line.966"></a>
975 <span class="sourceLineNo">967</span> try (final BackupSystemTable sysTable = new BackupSystemTable(conn)) {<a name="line.967"></a>
976 <span class="sourceLineNo">968</span> List&lt;TableName&gt; tables = sysTable.describeBackupSet(setName);<a name="line.968"></a>
977 <span class="sourceLineNo">969</span> BackupSet set = tables == null ? null : new BackupSet(setName, tables);<a name="line.969"></a>
978 <span class="sourceLineNo">970</span> if (set == null) {<a name="line.970"></a>
979 <span class="sourceLineNo">971</span> System.out.println("Set '" + setName + "' does not exist.");<a name="line.971"></a>
980 <span class="sourceLineNo">972</span> } else {<a name="line.972"></a>
981 <span class="sourceLineNo">973</span> System.out.println(set);<a name="line.973"></a>
982 <span class="sourceLineNo">974</span> }<a name="line.974"></a>
983 <span class="sourceLineNo">975</span> }<a name="line.975"></a>
984 <span class="sourceLineNo">976</span> }<a name="line.976"></a>
985 <span class="sourceLineNo">977</span><a name="line.977"></a>
986 <span class="sourceLineNo">978</span> private void processSetDelete(String[] args) throws IOException {<a name="line.978"></a>
987 <span class="sourceLineNo">979</span> if (args == null || args.length != 3) {<a name="line.979"></a>
988 <span class="sourceLineNo">980</span> printUsage();<a name="line.980"></a>
989 <span class="sourceLineNo">981</span> throw new IOException(INCORRECT_USAGE);<a name="line.981"></a>
990 <span class="sourceLineNo">982</span> }<a name="line.982"></a>
991 <span class="sourceLineNo">983</span> super.execute();<a name="line.983"></a>
992 <span class="sourceLineNo">984</span><a name="line.984"></a>
993 <span class="sourceLineNo">985</span> String setName = args[2];<a name="line.985"></a>
994 <span class="sourceLineNo">986</span> try (final BackupAdminImpl admin = new BackupAdminImpl(conn)) {<a name="line.986"></a>
995 <span class="sourceLineNo">987</span> boolean result = admin.deleteBackupSet(setName);<a name="line.987"></a>
996 <span class="sourceLineNo">988</span> if (result) {<a name="line.988"></a>
997 <span class="sourceLineNo">989</span> System.out.println("Delete set " + setName + " OK.");<a name="line.989"></a>
998 <span class="sourceLineNo">990</span> } else {<a name="line.990"></a>
999 <span class="sourceLineNo">991</span> System.out.println("Set " + setName + " does not exist");<a name="line.991"></a>
1000 <span class="sourceLineNo">992</span> }<a name="line.992"></a>
1001 <span class="sourceLineNo">993</span> }<a name="line.993"></a>
1002 <span class="sourceLineNo">994</span> }<a name="line.994"></a>
1003 <span class="sourceLineNo">995</span><a name="line.995"></a>
1004 <span class="sourceLineNo">996</span> private void processSetRemove(String[] args) throws IOException {<a name="line.996"></a>
1005 <span class="sourceLineNo">997</span> if (args == null || args.length != 4) {<a name="line.997"></a>
1006 <span class="sourceLineNo">998</span> printUsage();<a name="line.998"></a>
1007 <span class="sourceLineNo">999</span> throw new IOException(INCORRECT_USAGE);<a name="line.999"></a>
1008 <span class="sourceLineNo">1000</span> }<a name="line.1000"></a>
1009 <span class="sourceLineNo">1001</span> super.execute();<a name="line.1001"></a>
1010 <span class="sourceLineNo">1002</span><a name="line.1002"></a>
1011 <span class="sourceLineNo">1003</span> String setName = args[2];<a name="line.1003"></a>
1012 <span class="sourceLineNo">1004</span> String[] tables = args[3].split(",");<a name="line.1004"></a>
1013 <span class="sourceLineNo">1005</span> TableName[] tableNames = toTableNames(tables);<a name="line.1005"></a>
1014 <span class="sourceLineNo">1006</span> try (final BackupAdminImpl admin = new BackupAdminImpl(conn)) {<a name="line.1006"></a>
1015 <span class="sourceLineNo">1007</span> admin.removeFromBackupSet(setName, tableNames);<a name="line.1007"></a>
1016 <span class="sourceLineNo">1008</span> }<a name="line.1008"></a>
1017 <span class="sourceLineNo">1009</span> }<a name="line.1009"></a>
1018 <span class="sourceLineNo">1010</span><a name="line.1010"></a>
1019 <span class="sourceLineNo">1011</span> private TableName[] toTableNames(String[] tables) {<a name="line.1011"></a>
1020 <span class="sourceLineNo">1012</span> TableName[] arr = new TableName[tables.length];<a name="line.1012"></a>
1021 <span class="sourceLineNo">1013</span> for (int i = 0; i &lt; tables.length; i++) {<a name="line.1013"></a>
1022 <span class="sourceLineNo">1014</span> arr[i] = TableName.valueOf(tables[i]);<a name="line.1014"></a>
1023 <span class="sourceLineNo">1015</span> }<a name="line.1015"></a>
1024 <span class="sourceLineNo">1016</span> return arr;<a name="line.1016"></a>
1025 <span class="sourceLineNo">1017</span> }<a name="line.1017"></a>
1026 <span class="sourceLineNo">1018</span><a name="line.1018"></a>
1027 <span class="sourceLineNo">1019</span> private void processSetAdd(String[] args) throws IOException {<a name="line.1019"></a>
1028 <span class="sourceLineNo">1020</span> if (args == null || args.length != 4) {<a name="line.1020"></a>
1029 <span class="sourceLineNo">1021</span> printUsage();<a name="line.1021"></a>
1030 <span class="sourceLineNo">1022</span> throw new IOException(INCORRECT_USAGE);<a name="line.1022"></a>
1031 <span class="sourceLineNo">1023</span> }<a name="line.1023"></a>
1032 <span class="sourceLineNo">1024</span> super.execute();<a name="line.1024"></a>
1033 <span class="sourceLineNo">1025</span><a name="line.1025"></a>
1034 <span class="sourceLineNo">1026</span> String setName = args[2];<a name="line.1026"></a>
1035 <span class="sourceLineNo">1027</span> String[] tables = args[3].split(",");<a name="line.1027"></a>
1036 <span class="sourceLineNo">1028</span> TableName[] tableNames = new TableName[tables.length];<a name="line.1028"></a>
1037 <span class="sourceLineNo">1029</span> for (int i = 0; i &lt; tables.length; i++) {<a name="line.1029"></a>
1038 <span class="sourceLineNo">1030</span> tableNames[i] = TableName.valueOf(tables[i]);<a name="line.1030"></a>
1039 <span class="sourceLineNo">1031</span> }<a name="line.1031"></a>
1040 <span class="sourceLineNo">1032</span> try (final BackupAdminImpl admin = new BackupAdminImpl(conn)) {<a name="line.1032"></a>
1041 <span class="sourceLineNo">1033</span> admin.addToBackupSet(setName, tableNames);<a name="line.1033"></a>
1042 <span class="sourceLineNo">1034</span> }<a name="line.1034"></a>
1043 <span class="sourceLineNo">1035</span><a name="line.1035"></a>
1044 <span class="sourceLineNo">1036</span> }<a name="line.1036"></a>
1045 <span class="sourceLineNo">1037</span><a name="line.1037"></a>
1046 <span class="sourceLineNo">1038</span> private BackupCommand getCommand(String cmdStr) throws IOException {<a name="line.1038"></a>
1047 <span class="sourceLineNo">1039</span> switch (cmdStr) {<a name="line.1039"></a>
1048 <span class="sourceLineNo">1040</span> case SET_ADD_CMD:<a name="line.1040"></a>
1049 <span class="sourceLineNo">1041</span> return BackupCommand.SET_ADD;<a name="line.1041"></a>
1050 <span class="sourceLineNo">1042</span> case SET_REMOVE_CMD:<a name="line.1042"></a>
1051 <span class="sourceLineNo">1043</span> return BackupCommand.SET_REMOVE;<a name="line.1043"></a>
1052 <span class="sourceLineNo">1044</span> case SET_DELETE_CMD:<a name="line.1044"></a>
1053 <span class="sourceLineNo">1045</span> return BackupCommand.SET_DELETE;<a name="line.1045"></a>
1054 <span class="sourceLineNo">1046</span> case SET_DESCRIBE_CMD:<a name="line.1046"></a>
1055 <span class="sourceLineNo">1047</span> return BackupCommand.SET_DESCRIBE;<a name="line.1047"></a>
1056 <span class="sourceLineNo">1048</span> case SET_LIST_CMD:<a name="line.1048"></a>
1057 <span class="sourceLineNo">1049</span> return BackupCommand.SET_LIST;<a name="line.1049"></a>
1058 <span class="sourceLineNo">1050</span> default:<a name="line.1050"></a>
1059 <span class="sourceLineNo">1051</span> System.out.println("ERROR: Unknown command for 'set' :" + cmdStr);<a name="line.1051"></a>
1060 <span class="sourceLineNo">1052</span> printUsage();<a name="line.1052"></a>
1061 <span class="sourceLineNo">1053</span> throw new IOException(INCORRECT_USAGE);<a name="line.1053"></a>
1062 <span class="sourceLineNo">1054</span> }<a name="line.1054"></a>
1063 <span class="sourceLineNo">1055</span> }<a name="line.1055"></a>
1064 <span class="sourceLineNo">1056</span><a name="line.1056"></a>
1065 <span class="sourceLineNo">1057</span> @Override<a name="line.1057"></a>
1066 <span class="sourceLineNo">1058</span> protected void printUsage() {<a name="line.1058"></a>
1067 <span class="sourceLineNo">1059</span> System.out.println(SET_CMD_USAGE);<a name="line.1059"></a>
1068 <span class="sourceLineNo">1060</span> }<a name="line.1060"></a>
1069 <span class="sourceLineNo">1061</span> }<a name="line.1061"></a>
1070 <span class="sourceLineNo">1062</span>}<a name="line.1062"></a>
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131 </pre>
1132 </div>
1133 </body>
1134 </html>