http://git-wip-us.apache.org/repos/asf/hbase-site/blob/8f09a71d/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/store/wal/WALProcedureStore.LeaseRecovery.html
----------------------------------------------------------------------
diff --git
a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/store/wal/WALProcedureStore.LeaseRecovery.html
b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/store/wal/WALProcedureStore.LeaseRecovery.html
index 9b964f6..98ef11a 100644
---
a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/store/wal/WALProcedureStore.LeaseRecovery.html
+++
b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/store/wal/WALProcedureStore.LeaseRecovery.html
@@ -105,7 +105,7 @@
<span class="sourceLineNo">097</span> * will first be initialized to the
oldest file's tracker(which is stored in the trailer), using the<a
name="line.97"></a>
<span class="sourceLineNo">098</span> * method {@link
ProcedureStoreTracker#resetTo(ProcedureStoreTracker, boolean)}, and then merge
it<a name="line.98"></a>
<span class="sourceLineNo">099</span> * with the tracker of every newer wal
files, using the<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * {@link
ProcedureStoreTracker#setDeletedIfModifiedInBoth(ProcedureStoreTracker,
boolean)}.<a name="line.100"></a>
+<span class="sourceLineNo">100</span> * {@link
ProcedureStoreTracker#setDeletedIfModifiedInBoth(ProcedureStoreTracker)}.<a
name="line.100"></a>
<span class="sourceLineNo">101</span> * If we find out<a name="line.101"></a>
<span class="sourceLineNo">102</span> * that all the modified procedures for
the oldest wal file are modified or deleted in newer wal<a name="line.102"></a>
<span class="sourceLineNo">103</span> * files, then we can delete it. This is
because that, every time we call<a name="line.103"></a>
@@ -1181,244 +1181,243 @@
<span class="sourceLineNo">1173</span> }<a name="line.1173"></a>
<span class="sourceLineNo">1174</span><a name="line.1174"></a>
<span class="sourceLineNo">1175</span> // compute the holding tracker.<a
name="line.1175"></a>
-<span class="sourceLineNo">1176</span> // - the first WAL is used for the
'updates'<a name="line.1176"></a>
-<span class="sourceLineNo">1177</span> // - the global tracker is passed
in first to decide which procedures are not<a name="line.1177"></a>
-<span class="sourceLineNo">1178</span> // exist anymore, so we can mark
them as deleted in holdingCleanupTracker.<a name="line.1178"></a>
-<span class="sourceLineNo">1179</span> // Only global tracker have the
whole picture here.<a name="line.1179"></a>
-<span class="sourceLineNo">1180</span> // - the other WALs are scanned to
remove procs already updated in a newer wal.<a name="line.1180"></a>
-<span class="sourceLineNo">1181</span> // If it is updated in a newer
wal, we can mark it as delelted in holdingCleanupTracker<a name="line.1181"></a>
-<span class="sourceLineNo">1182</span> // But, we can not delete it if
it was shown deleted in the newer wal, as said<a name="line.1182"></a>
-<span class="sourceLineNo">1183</span> // above.<a name="line.1183"></a>
-<span class="sourceLineNo">1184</span> // TODO: exit early if
holdingCleanupTracker.isEmpty()<a name="line.1184"></a>
-<span class="sourceLineNo">1185</span>
holdingCleanupTracker.resetTo(logs.getFirst().getTracker(), true);<a
name="line.1185"></a>
-<span class="sourceLineNo">1186</span> //Passing in the global tracker, we
can delete the procedures not in the global<a name="line.1186"></a>
-<span class="sourceLineNo">1187</span> //tracker, because they are deleted
in the later logs<a name="line.1187"></a>
-<span class="sourceLineNo">1188</span>
holdingCleanupTracker.setDeletedIfModifiedInBoth(storeTracker, true);<a
name="line.1188"></a>
-<span class="sourceLineNo">1189</span> for (int i = 1, size = logs.size() -
1; i < size; ++i) {<a name="line.1189"></a>
-<span class="sourceLineNo">1190</span> // Set deleteIfNotExists to false
since a single log's tracker is passed in.<a name="line.1190"></a>
-<span class="sourceLineNo">1191</span> // Since a specific procedure may
not show up in the log at all(not executed or<a name="line.1191"></a>
-<span class="sourceLineNo">1192</span> // updated during the time), we
can not delete the procedure just because this log<a name="line.1192"></a>
-<span class="sourceLineNo">1193</span> // don't have the info of the
procedure. We can delete the procedure only if<a name="line.1193"></a>
-<span class="sourceLineNo">1194</span> // in this log's tracker, it was
cleanly showed that the procedure is modified or deleted<a name="line.1194"></a>
-<span class="sourceLineNo">1195</span> // in the corresponding
BitSetNode.<a name="line.1195"></a>
-<span class="sourceLineNo">1196</span>
holdingCleanupTracker.setDeletedIfModifiedInBoth(logs.get(i).getTracker(),
false);<a name="line.1196"></a>
-<span class="sourceLineNo">1197</span> }<a name="line.1197"></a>
-<span class="sourceLineNo">1198</span> }<a name="line.1198"></a>
-<span class="sourceLineNo">1199</span><a name="line.1199"></a>
-<span class="sourceLineNo">1200</span> /**<a name="line.1200"></a>
-<span class="sourceLineNo">1201</span> * Remove all logs with logId <=
{@code lastLogId}.<a name="line.1201"></a>
-<span class="sourceLineNo">1202</span> */<a name="line.1202"></a>
-<span class="sourceLineNo">1203</span> private void removeAllLogs(long
lastLogId, String why) {<a name="line.1203"></a>
-<span class="sourceLineNo">1204</span> if (logs.size() <= 1) {<a
name="line.1204"></a>
-<span class="sourceLineNo">1205</span> return;<a name="line.1205"></a>
-<span class="sourceLineNo">1206</span> }<a name="line.1206"></a>
-<span class="sourceLineNo">1207</span><a name="line.1207"></a>
-<span class="sourceLineNo">1208</span> LOG.info("Remove all state logs with
ID less than {}, since {}", lastLogId, why);<a name="line.1208"></a>
-<span class="sourceLineNo">1209</span><a name="line.1209"></a>
-<span class="sourceLineNo">1210</span> boolean removed = false;<a
name="line.1210"></a>
-<span class="sourceLineNo">1211</span> while (logs.size() > 1) {<a
name="line.1211"></a>
-<span class="sourceLineNo">1212</span> ProcedureWALFile log =
logs.getFirst();<a name="line.1212"></a>
-<span class="sourceLineNo">1213</span> if (lastLogId < log.getLogId())
{<a name="line.1213"></a>
-<span class="sourceLineNo">1214</span> break;<a name="line.1214"></a>
-<span class="sourceLineNo">1215</span> }<a name="line.1215"></a>
-<span class="sourceLineNo">1216</span> removeLogFile(log,
walArchiveDir);<a name="line.1216"></a>
-<span class="sourceLineNo">1217</span> removed = true;<a
name="line.1217"></a>
-<span class="sourceLineNo">1218</span> }<a name="line.1218"></a>
-<span class="sourceLineNo">1219</span><a name="line.1219"></a>
-<span class="sourceLineNo">1220</span> if (removed) {<a
name="line.1220"></a>
-<span class="sourceLineNo">1221</span> buildHoldingCleanupTracker();<a
name="line.1221"></a>
-<span class="sourceLineNo">1222</span> }<a name="line.1222"></a>
-<span class="sourceLineNo">1223</span> }<a name="line.1223"></a>
-<span class="sourceLineNo">1224</span><a name="line.1224"></a>
-<span class="sourceLineNo">1225</span> private boolean removeLogFile(final
ProcedureWALFile log, final Path walArchiveDir) {<a name="line.1225"></a>
-<span class="sourceLineNo">1226</span> try {<a name="line.1226"></a>
-<span class="sourceLineNo">1227</span> LOG.trace("Removing log={}",
log);<a name="line.1227"></a>
-<span class="sourceLineNo">1228</span> log.removeFile(walArchiveDir);<a
name="line.1228"></a>
-<span class="sourceLineNo">1229</span> logs.remove(log);<a
name="line.1229"></a>
-<span class="sourceLineNo">1230</span> LOG.debug("Removed log={},
activeLogs={}", log, logs);<a name="line.1230"></a>
-<span class="sourceLineNo">1231</span> assert logs.size() > 0 :
"expected at least one log";<a name="line.1231"></a>
-<span class="sourceLineNo">1232</span> } catch (IOException e) {<a
name="line.1232"></a>
-<span class="sourceLineNo">1233</span> LOG.error("Unable to remove log: "
+ log, e);<a name="line.1233"></a>
-<span class="sourceLineNo">1234</span> return false;<a
name="line.1234"></a>
-<span class="sourceLineNo">1235</span> }<a name="line.1235"></a>
-<span class="sourceLineNo">1236</span> return true;<a name="line.1236"></a>
-<span class="sourceLineNo">1237</span> }<a name="line.1237"></a>
-<span class="sourceLineNo">1238</span><a name="line.1238"></a>
-<span class="sourceLineNo">1239</span> //
==========================================================================<a
name="line.1239"></a>
-<span class="sourceLineNo">1240</span> // FileSystem Log Files helpers<a
name="line.1240"></a>
-<span class="sourceLineNo">1241</span> //
==========================================================================<a
name="line.1241"></a>
-<span class="sourceLineNo">1242</span> public Path getWALDir() {<a
name="line.1242"></a>
-<span class="sourceLineNo">1243</span> return this.walDir;<a
name="line.1243"></a>
-<span class="sourceLineNo">1244</span> }<a name="line.1244"></a>
-<span class="sourceLineNo">1245</span><a name="line.1245"></a>
-<span class="sourceLineNo">1246</span> @VisibleForTesting<a
name="line.1246"></a>
-<span class="sourceLineNo">1247</span> Path getWalArchiveDir() {<a
name="line.1247"></a>
-<span class="sourceLineNo">1248</span> return this.walArchiveDir;<a
name="line.1248"></a>
-<span class="sourceLineNo">1249</span> }<a name="line.1249"></a>
-<span class="sourceLineNo">1250</span><a name="line.1250"></a>
-<span class="sourceLineNo">1251</span> public FileSystem getFileSystem() {<a
name="line.1251"></a>
-<span class="sourceLineNo">1252</span> return this.fs;<a
name="line.1252"></a>
-<span class="sourceLineNo">1253</span> }<a name="line.1253"></a>
-<span class="sourceLineNo">1254</span><a name="line.1254"></a>
-<span class="sourceLineNo">1255</span> protected Path getLogFilePath(final
long logId) throws IOException {<a name="line.1255"></a>
-<span class="sourceLineNo">1256</span> return new Path(walDir,
String.format(LOG_PREFIX + "%020d.log", logId));<a name="line.1256"></a>
-<span class="sourceLineNo">1257</span> }<a name="line.1257"></a>
-<span class="sourceLineNo">1258</span><a name="line.1258"></a>
-<span class="sourceLineNo">1259</span> private static long
getLogIdFromName(final String name) {<a name="line.1259"></a>
-<span class="sourceLineNo">1260</span> int end =
name.lastIndexOf(".log");<a name="line.1260"></a>
-<span class="sourceLineNo">1261</span> int start = name.lastIndexOf('-') +
1;<a name="line.1261"></a>
-<span class="sourceLineNo">1262</span> return
Long.parseLong(name.substring(start, end));<a name="line.1262"></a>
-<span class="sourceLineNo">1263</span> }<a name="line.1263"></a>
-<span class="sourceLineNo">1264</span><a name="line.1264"></a>
-<span class="sourceLineNo">1265</span> private static final PathFilter
WALS_PATH_FILTER = new PathFilter() {<a name="line.1265"></a>
-<span class="sourceLineNo">1266</span> @Override<a name="line.1266"></a>
-<span class="sourceLineNo">1267</span> public boolean accept(Path path) {<a
name="line.1267"></a>
-<span class="sourceLineNo">1268</span> String name = path.getName();<a
name="line.1268"></a>
-<span class="sourceLineNo">1269</span> return name.startsWith(LOG_PREFIX)
&& name.endsWith(".log");<a name="line.1269"></a>
-<span class="sourceLineNo">1270</span> }<a name="line.1270"></a>
-<span class="sourceLineNo">1271</span> };<a name="line.1271"></a>
-<span class="sourceLineNo">1272</span><a name="line.1272"></a>
-<span class="sourceLineNo">1273</span> private static final
Comparator<FileStatus> FILE_STATUS_ID_COMPARATOR =<a name="line.1273"></a>
-<span class="sourceLineNo">1274</span> new Comparator<FileStatus>()
{<a name="line.1274"></a>
-<span class="sourceLineNo">1275</span> @Override<a name="line.1275"></a>
-<span class="sourceLineNo">1276</span> public int compare(FileStatus a,
FileStatus b) {<a name="line.1276"></a>
-<span class="sourceLineNo">1277</span> final long aId =
getLogIdFromName(a.getPath().getName());<a name="line.1277"></a>
-<span class="sourceLineNo">1278</span> final long bId =
getLogIdFromName(b.getPath().getName());<a name="line.1278"></a>
-<span class="sourceLineNo">1279</span> return Long.compare(aId, bId);<a
name="line.1279"></a>
-<span class="sourceLineNo">1280</span> }<a name="line.1280"></a>
-<span class="sourceLineNo">1281</span> };<a name="line.1281"></a>
-<span class="sourceLineNo">1282</span><a name="line.1282"></a>
-<span class="sourceLineNo">1283</span> private FileStatus[] getLogFiles()
throws IOException {<a name="line.1283"></a>
-<span class="sourceLineNo">1284</span> try {<a name="line.1284"></a>
-<span class="sourceLineNo">1285</span> FileStatus[] files =
fs.listStatus(walDir, WALS_PATH_FILTER);<a name="line.1285"></a>
-<span class="sourceLineNo">1286</span> Arrays.sort(files,
FILE_STATUS_ID_COMPARATOR);<a name="line.1286"></a>
-<span class="sourceLineNo">1287</span> return files;<a
name="line.1287"></a>
-<span class="sourceLineNo">1288</span> } catch (FileNotFoundException e)
{<a name="line.1288"></a>
-<span class="sourceLineNo">1289</span> LOG.warn("Log directory not found:
" + e.getMessage());<a name="line.1289"></a>
-<span class="sourceLineNo">1290</span> return null;<a
name="line.1290"></a>
-<span class="sourceLineNo">1291</span> }<a name="line.1291"></a>
-<span class="sourceLineNo">1292</span> }<a name="line.1292"></a>
-<span class="sourceLineNo">1293</span><a name="line.1293"></a>
-<span class="sourceLineNo">1294</span> /**<a name="line.1294"></a>
-<span class="sourceLineNo">1295</span> * Make sure that the file set are
gotten by calling {@link #getLogFiles()}, where we will sort<a
name="line.1295"></a>
-<span class="sourceLineNo">1296</span> * the file set by log id.<a
name="line.1296"></a>
-<span class="sourceLineNo">1297</span> * @return Max-LogID of the specified
log file set<a name="line.1297"></a>
-<span class="sourceLineNo">1298</span> */<a name="line.1298"></a>
-<span class="sourceLineNo">1299</span> private static long
getMaxLogId(FileStatus[] logFiles) {<a name="line.1299"></a>
-<span class="sourceLineNo">1300</span> if (logFiles == null ||
logFiles.length == 0) {<a name="line.1300"></a>
-<span class="sourceLineNo">1301</span> return 0L;<a name="line.1301"></a>
-<span class="sourceLineNo">1302</span> }<a name="line.1302"></a>
-<span class="sourceLineNo">1303</span> return
getLogIdFromName(logFiles[logFiles.length - 1].getPath().getName());<a
name="line.1303"></a>
-<span class="sourceLineNo">1304</span> }<a name="line.1304"></a>
-<span class="sourceLineNo">1305</span><a name="line.1305"></a>
-<span class="sourceLineNo">1306</span> /**<a name="line.1306"></a>
-<span class="sourceLineNo">1307</span> * Make sure that the file set are
gotten by calling {@link #getLogFiles()}, where we will sort<a
name="line.1307"></a>
-<span class="sourceLineNo">1308</span> * the file set by log id.<a
name="line.1308"></a>
-<span class="sourceLineNo">1309</span> * @return Max-LogID of the specified
log file set<a name="line.1309"></a>
-<span class="sourceLineNo">1310</span> */<a name="line.1310"></a>
-<span class="sourceLineNo">1311</span> private long initOldLogs(FileStatus[]
logFiles) throws IOException {<a name="line.1311"></a>
-<span class="sourceLineNo">1312</span> if (logFiles == null ||
logFiles.length == 0) {<a name="line.1312"></a>
-<span class="sourceLineNo">1313</span> return 0L;<a name="line.1313"></a>
-<span class="sourceLineNo">1314</span> }<a name="line.1314"></a>
-<span class="sourceLineNo">1315</span> long maxLogId = 0;<a
name="line.1315"></a>
-<span class="sourceLineNo">1316</span> for (int i = 0; i <
logFiles.length; ++i) {<a name="line.1316"></a>
-<span class="sourceLineNo">1317</span> final Path logPath =
logFiles[i].getPath();<a name="line.1317"></a>
-<span class="sourceLineNo">1318</span> leaseRecovery.recoverFileLease(fs,
logPath);<a name="line.1318"></a>
-<span class="sourceLineNo">1319</span> if (!isRunning()) {<a
name="line.1319"></a>
-<span class="sourceLineNo">1320</span> throw new IOException("wal
aborting");<a name="line.1320"></a>
-<span class="sourceLineNo">1321</span> }<a name="line.1321"></a>
-<span class="sourceLineNo">1322</span><a name="line.1322"></a>
-<span class="sourceLineNo">1323</span> maxLogId = Math.max(maxLogId,
getLogIdFromName(logPath.getName()));<a name="line.1323"></a>
-<span class="sourceLineNo">1324</span> ProcedureWALFile log =
initOldLog(logFiles[i], this.walArchiveDir);<a name="line.1324"></a>
-<span class="sourceLineNo">1325</span> if (log != null) {<a
name="line.1325"></a>
-<span class="sourceLineNo">1326</span> this.logs.add(log);<a
name="line.1326"></a>
-<span class="sourceLineNo">1327</span> }<a name="line.1327"></a>
-<span class="sourceLineNo">1328</span> }<a name="line.1328"></a>
-<span class="sourceLineNo">1329</span> initTrackerFromOldLogs();<a
name="line.1329"></a>
-<span class="sourceLineNo">1330</span> return maxLogId;<a
name="line.1330"></a>
-<span class="sourceLineNo">1331</span> }<a name="line.1331"></a>
-<span class="sourceLineNo">1332</span><a name="line.1332"></a>
-<span class="sourceLineNo">1333</span> /**<a name="line.1333"></a>
-<span class="sourceLineNo">1334</span> * If last log's tracker is not null,
use it as {@link #storeTracker}. Otherwise, set storeTracker<a
name="line.1334"></a>
-<span class="sourceLineNo">1335</span> * as partial, and let {@link
ProcedureWALFormatReader} rebuild it using entries in the log.<a
name="line.1335"></a>
-<span class="sourceLineNo">1336</span> */<a name="line.1336"></a>
-<span class="sourceLineNo">1337</span> private void initTrackerFromOldLogs()
{<a name="line.1337"></a>
-<span class="sourceLineNo">1338</span> if (logs.isEmpty() || !isRunning())
{<a name="line.1338"></a>
-<span class="sourceLineNo">1339</span> return;<a name="line.1339"></a>
-<span class="sourceLineNo">1340</span> }<a name="line.1340"></a>
-<span class="sourceLineNo">1341</span> ProcedureWALFile log =
logs.getLast();<a name="line.1341"></a>
-<span class="sourceLineNo">1342</span> if (!log.getTracker().isPartial())
{<a name="line.1342"></a>
-<span class="sourceLineNo">1343</span>
storeTracker.resetTo(log.getTracker());<a name="line.1343"></a>
-<span class="sourceLineNo">1344</span> } else {<a name="line.1344"></a>
-<span class="sourceLineNo">1345</span> storeTracker.reset();<a
name="line.1345"></a>
-<span class="sourceLineNo">1346</span>
storeTracker.setPartialFlag(true);<a name="line.1346"></a>
-<span class="sourceLineNo">1347</span> }<a name="line.1347"></a>
-<span class="sourceLineNo">1348</span> }<a name="line.1348"></a>
-<span class="sourceLineNo">1349</span><a name="line.1349"></a>
-<span class="sourceLineNo">1350</span> /**<a name="line.1350"></a>
-<span class="sourceLineNo">1351</span> * Loads given log file and it's
tracker.<a name="line.1351"></a>
-<span class="sourceLineNo">1352</span> */<a name="line.1352"></a>
-<span class="sourceLineNo">1353</span> private ProcedureWALFile
initOldLog(final FileStatus logFile, final Path walArchiveDir)<a
name="line.1353"></a>
-<span class="sourceLineNo">1354</span> throws IOException {<a
name="line.1354"></a>
-<span class="sourceLineNo">1355</span> final ProcedureWALFile log = new
ProcedureWALFile(fs, logFile);<a name="line.1355"></a>
-<span class="sourceLineNo">1356</span> if (logFile.getLen() == 0) {<a
name="line.1356"></a>
-<span class="sourceLineNo">1357</span> LOG.warn("Remove uninitialized
log: {}", logFile);<a name="line.1357"></a>
-<span class="sourceLineNo">1358</span> log.removeFile(walArchiveDir);<a
name="line.1358"></a>
-<span class="sourceLineNo">1359</span> return null;<a
name="line.1359"></a>
-<span class="sourceLineNo">1360</span> }<a name="line.1360"></a>
-<span class="sourceLineNo">1361</span> LOG.debug("Opening Pv2 {}",
logFile);<a name="line.1361"></a>
-<span class="sourceLineNo">1362</span> try {<a name="line.1362"></a>
-<span class="sourceLineNo">1363</span> log.open();<a name="line.1363"></a>
-<span class="sourceLineNo">1364</span> } catch
(ProcedureWALFormat.InvalidWALDataException e) {<a name="line.1364"></a>
-<span class="sourceLineNo">1365</span> LOG.warn("Remove uninitialized
log: {}", logFile, e);<a name="line.1365"></a>
-<span class="sourceLineNo">1366</span> log.removeFile(walArchiveDir);<a
name="line.1366"></a>
-<span class="sourceLineNo">1367</span> return null;<a
name="line.1367"></a>
-<span class="sourceLineNo">1368</span> } catch (IOException e) {<a
name="line.1368"></a>
-<span class="sourceLineNo">1369</span> String msg = "Unable to read state
log: " + logFile;<a name="line.1369"></a>
-<span class="sourceLineNo">1370</span> LOG.error(msg, e);<a
name="line.1370"></a>
-<span class="sourceLineNo">1371</span> throw new IOException(msg, e);<a
name="line.1371"></a>
-<span class="sourceLineNo">1372</span> }<a name="line.1372"></a>
-<span class="sourceLineNo">1373</span><a name="line.1373"></a>
-<span class="sourceLineNo">1374</span> try {<a name="line.1374"></a>
-<span class="sourceLineNo">1375</span> log.readTracker();<a
name="line.1375"></a>
-<span class="sourceLineNo">1376</span> } catch (IOException e) {<a
name="line.1376"></a>
-<span class="sourceLineNo">1377</span> log.getTracker().reset();<a
name="line.1377"></a>
-<span class="sourceLineNo">1378</span>
log.getTracker().setPartialFlag(true);<a name="line.1378"></a>
-<span class="sourceLineNo">1379</span> LOG.warn("Unable to read tracker
for {}", log, e);<a name="line.1379"></a>
-<span class="sourceLineNo">1380</span> }<a name="line.1380"></a>
-<span class="sourceLineNo">1381</span><a name="line.1381"></a>
-<span class="sourceLineNo">1382</span> log.close();<a name="line.1382"></a>
-<span class="sourceLineNo">1383</span> return log;<a name="line.1383"></a>
-<span class="sourceLineNo">1384</span> }<a name="line.1384"></a>
-<span class="sourceLineNo">1385</span><a name="line.1385"></a>
-<span class="sourceLineNo">1386</span> /**<a name="line.1386"></a>
-<span class="sourceLineNo">1387</span> * Parses a directory of WALs building
up ProcedureState.<a name="line.1387"></a>
-<span class="sourceLineNo">1388</span> * For testing parse and profiling.<a
name="line.1388"></a>
-<span class="sourceLineNo">1389</span> * @param args Include pointer to
directory of WAL files for a store instance to parse & load.<a
name="line.1389"></a>
-<span class="sourceLineNo">1390</span> */<a name="line.1390"></a>
-<span class="sourceLineNo">1391</span> public static void main(String []
args) throws IOException {<a name="line.1391"></a>
-<span class="sourceLineNo">1392</span> Configuration conf =
HBaseConfiguration.create();<a name="line.1392"></a>
-<span class="sourceLineNo">1393</span> if (args == null || args.length !=
1) {<a name="line.1393"></a>
-<span class="sourceLineNo">1394</span> System.out.println("ERROR: Empty
arguments list; pass path to MASTERPROCWALS_DIR.");<a name="line.1394"></a>
-<span class="sourceLineNo">1395</span> System.out.println("Usage:
WALProcedureStore MASTERPROCWALS_DIR");<a name="line.1395"></a>
-<span class="sourceLineNo">1396</span> System.exit(-1);<a
name="line.1396"></a>
-<span class="sourceLineNo">1397</span> }<a name="line.1397"></a>
-<span class="sourceLineNo">1398</span> WALProcedureStore store = new
WALProcedureStore(conf, new Path(args[0]), null,<a name="line.1398"></a>
-<span class="sourceLineNo">1399</span> new
WALProcedureStore.LeaseRecovery() {<a name="line.1399"></a>
-<span class="sourceLineNo">1400</span> @Override<a name="line.1400"></a>
-<span class="sourceLineNo">1401</span> public void
recoverFileLease(FileSystem fs, Path path) throws IOException {<a
name="line.1401"></a>
-<span class="sourceLineNo">1402</span> // no-op<a
name="line.1402"></a>
-<span class="sourceLineNo">1403</span> }<a name="line.1403"></a>
-<span class="sourceLineNo">1404</span> });<a name="line.1404"></a>
-<span class="sourceLineNo">1405</span> try {<a name="line.1405"></a>
-<span class="sourceLineNo">1406</span> store.start(16);<a
name="line.1406"></a>
-<span class="sourceLineNo">1407</span> ProcedureExecutor<?> pe =
new ProcedureExecutor<>(conf, new Object()/*Pass anything*/, store);<a
name="line.1407"></a>
-<span class="sourceLineNo">1408</span> pe.init(1, true);<a
name="line.1408"></a>
-<span class="sourceLineNo">1409</span> } finally {<a name="line.1409"></a>
-<span class="sourceLineNo">1410</span> store.stop(true);<a
name="line.1410"></a>
-<span class="sourceLineNo">1411</span> }<a name="line.1411"></a>
-<span class="sourceLineNo">1412</span> }<a name="line.1412"></a>
-<span class="sourceLineNo">1413</span>}<a name="line.1413"></a>
+<span class="sourceLineNo">1176</span> // - the first WAL is used for the
'updates'<a name="line.1176"></a>
+<span class="sourceLineNo">1177</span> // - the global tracker will be used
to determine whether a procedure has been deleted<a name="line.1177"></a>
+<span class="sourceLineNo">1178</span> // - other trackers will be used to
determine whether a procedure has been updated, as a deleted<a
name="line.1178"></a>
+<span class="sourceLineNo">1179</span> // procedure can always be detected
by checking the global tracker, we can save the deleted<a name="line.1179"></a>
+<span class="sourceLineNo">1180</span> // checks when applying other
trackers<a name="line.1180"></a>
+<span class="sourceLineNo">1181</span>
holdingCleanupTracker.resetTo(logs.getFirst().getTracker(), true);<a
name="line.1181"></a>
+<span class="sourceLineNo">1182</span>
holdingCleanupTracker.setDeletedIfDeletedByThem(storeTracker);<a
name="line.1182"></a>
+<span class="sourceLineNo">1183</span> // the logs is a linked list, so
avoid calling get(index) on it.<a name="line.1183"></a>
+<span class="sourceLineNo">1184</span> Iterator<ProcedureWALFile>
iter = logs.iterator();<a name="line.1184"></a>
+<span class="sourceLineNo">1185</span> // skip the tracker for the first
file when creating the iterator.<a name="line.1185"></a>
+<span class="sourceLineNo">1186</span> iter.next();<a name="line.1186"></a>
+<span class="sourceLineNo">1187</span> ProcedureStoreTracker tracker =
iter.next().getTracker();<a name="line.1187"></a>
+<span class="sourceLineNo">1188</span> // testing iter.hasNext after
calling iter.next to skip applying the tracker for last file,<a
name="line.1188"></a>
+<span class="sourceLineNo">1189</span> // which is just the storeTracker
above.<a name="line.1189"></a>
+<span class="sourceLineNo">1190</span> while (iter.hasNext()) {<a
name="line.1190"></a>
+<span class="sourceLineNo">1191</span>
holdingCleanupTracker.setDeletedIfModifiedInBoth(tracker);<a
name="line.1191"></a>
+<span class="sourceLineNo">1192</span> if
(holdingCleanupTracker.isEmpty()) {<a name="line.1192"></a>
+<span class="sourceLineNo">1193</span> break;<a name="line.1193"></a>
+<span class="sourceLineNo">1194</span> }<a name="line.1194"></a>
+<span class="sourceLineNo">1195</span> iter.next();<a
name="line.1195"></a>
+<span class="sourceLineNo">1196</span> }<a name="line.1196"></a>
+<span class="sourceLineNo">1197</span> }<a name="line.1197"></a>
+<span class="sourceLineNo">1198</span><a name="line.1198"></a>
+<span class="sourceLineNo">1199</span> /**<a name="line.1199"></a>
+<span class="sourceLineNo">1200</span> * Remove all logs with logId <=
{@code lastLogId}.<a name="line.1200"></a>
+<span class="sourceLineNo">1201</span> */<a name="line.1201"></a>
+<span class="sourceLineNo">1202</span> private void removeAllLogs(long
lastLogId, String why) {<a name="line.1202"></a>
+<span class="sourceLineNo">1203</span> if (logs.size() <= 1) {<a
name="line.1203"></a>
+<span class="sourceLineNo">1204</span> return;<a name="line.1204"></a>
+<span class="sourceLineNo">1205</span> }<a name="line.1205"></a>
+<span class="sourceLineNo">1206</span><a name="line.1206"></a>
+<span class="sourceLineNo">1207</span> LOG.info("Remove all state logs with
ID less than {}, since {}", lastLogId, why);<a name="line.1207"></a>
+<span class="sourceLineNo">1208</span><a name="line.1208"></a>
+<span class="sourceLineNo">1209</span> boolean removed = false;<a
name="line.1209"></a>
+<span class="sourceLineNo">1210</span> while (logs.size() > 1) {<a
name="line.1210"></a>
+<span class="sourceLineNo">1211</span> ProcedureWALFile log =
logs.getFirst();<a name="line.1211"></a>
+<span class="sourceLineNo">1212</span> if (lastLogId < log.getLogId())
{<a name="line.1212"></a>
+<span class="sourceLineNo">1213</span> break;<a name="line.1213"></a>
+<span class="sourceLineNo">1214</span> }<a name="line.1214"></a>
+<span class="sourceLineNo">1215</span> removeLogFile(log,
walArchiveDir);<a name="line.1215"></a>
+<span class="sourceLineNo">1216</span> removed = true;<a
name="line.1216"></a>
+<span class="sourceLineNo">1217</span> }<a name="line.1217"></a>
+<span class="sourceLineNo">1218</span><a name="line.1218"></a>
+<span class="sourceLineNo">1219</span> if (removed) {<a
name="line.1219"></a>
+<span class="sourceLineNo">1220</span> buildHoldingCleanupTracker();<a
name="line.1220"></a>
+<span class="sourceLineNo">1221</span> }<a name="line.1221"></a>
+<span class="sourceLineNo">1222</span> }<a name="line.1222"></a>
+<span class="sourceLineNo">1223</span><a name="line.1223"></a>
+<span class="sourceLineNo">1224</span> private boolean removeLogFile(final
ProcedureWALFile log, final Path walArchiveDir) {<a name="line.1224"></a>
+<span class="sourceLineNo">1225</span> try {<a name="line.1225"></a>
+<span class="sourceLineNo">1226</span> LOG.trace("Removing log={}",
log);<a name="line.1226"></a>
+<span class="sourceLineNo">1227</span> log.removeFile(walArchiveDir);<a
name="line.1227"></a>
+<span class="sourceLineNo">1228</span> logs.remove(log);<a
name="line.1228"></a>
+<span class="sourceLineNo">1229</span> LOG.debug("Removed log={},
activeLogs={}", log, logs);<a name="line.1229"></a>
+<span class="sourceLineNo">1230</span> assert logs.size() > 0 :
"expected at least one log";<a name="line.1230"></a>
+<span class="sourceLineNo">1231</span> } catch (IOException e) {<a
name="line.1231"></a>
+<span class="sourceLineNo">1232</span> LOG.error("Unable to remove log: "
+ log, e);<a name="line.1232"></a>
+<span class="sourceLineNo">1233</span> return false;<a
name="line.1233"></a>
+<span class="sourceLineNo">1234</span> }<a name="line.1234"></a>
+<span class="sourceLineNo">1235</span> return true;<a name="line.1235"></a>
+<span class="sourceLineNo">1236</span> }<a name="line.1236"></a>
+<span class="sourceLineNo">1237</span><a name="line.1237"></a>
+<span class="sourceLineNo">1238</span> //
==========================================================================<a
name="line.1238"></a>
+<span class="sourceLineNo">1239</span> // FileSystem Log Files helpers<a
name="line.1239"></a>
+<span class="sourceLineNo">1240</span> //
==========================================================================<a
name="line.1240"></a>
+<span class="sourceLineNo">1241</span> public Path getWALDir() {<a
name="line.1241"></a>
+<span class="sourceLineNo">1242</span> return this.walDir;<a
name="line.1242"></a>
+<span class="sourceLineNo">1243</span> }<a name="line.1243"></a>
+<span class="sourceLineNo">1244</span><a name="line.1244"></a>
+<span class="sourceLineNo">1245</span> @VisibleForTesting<a
name="line.1245"></a>
+<span class="sourceLineNo">1246</span> Path getWalArchiveDir() {<a
name="line.1246"></a>
+<span class="sourceLineNo">1247</span> return this.walArchiveDir;<a
name="line.1247"></a>
+<span class="sourceLineNo">1248</span> }<a name="line.1248"></a>
+<span class="sourceLineNo">1249</span><a name="line.1249"></a>
+<span class="sourceLineNo">1250</span> public FileSystem getFileSystem() {<a
name="line.1250"></a>
+<span class="sourceLineNo">1251</span> return this.fs;<a
name="line.1251"></a>
+<span class="sourceLineNo">1252</span> }<a name="line.1252"></a>
+<span class="sourceLineNo">1253</span><a name="line.1253"></a>
+<span class="sourceLineNo">1254</span> protected Path getLogFilePath(final
long logId) throws IOException {<a name="line.1254"></a>
+<span class="sourceLineNo">1255</span> return new Path(walDir,
String.format(LOG_PREFIX + "%020d.log", logId));<a name="line.1255"></a>
+<span class="sourceLineNo">1256</span> }<a name="line.1256"></a>
+<span class="sourceLineNo">1257</span><a name="line.1257"></a>
+<span class="sourceLineNo">1258</span> private static long
getLogIdFromName(final String name) {<a name="line.1258"></a>
+<span class="sourceLineNo">1259</span> int end =
name.lastIndexOf(".log");<a name="line.1259"></a>
+<span class="sourceLineNo">1260</span> int start = name.lastIndexOf('-') +
1;<a name="line.1260"></a>
+<span class="sourceLineNo">1261</span> return
Long.parseLong(name.substring(start, end));<a name="line.1261"></a>
+<span class="sourceLineNo">1262</span> }<a name="line.1262"></a>
+<span class="sourceLineNo">1263</span><a name="line.1263"></a>
+<span class="sourceLineNo">1264</span> private static final PathFilter
WALS_PATH_FILTER = new PathFilter() {<a name="line.1264"></a>
+<span class="sourceLineNo">1265</span> @Override<a name="line.1265"></a>
+<span class="sourceLineNo">1266</span> public boolean accept(Path path) {<a
name="line.1266"></a>
+<span class="sourceLineNo">1267</span> String name = path.getName();<a
name="line.1267"></a>
+<span class="sourceLineNo">1268</span> return name.startsWith(LOG_PREFIX)
&& name.endsWith(".log");<a name="line.1268"></a>
+<span class="sourceLineNo">1269</span> }<a name="line.1269"></a>
+<span class="sourceLineNo">1270</span> };<a name="line.1270"></a>
+<span class="sourceLineNo">1271</span><a name="line.1271"></a>
+<span class="sourceLineNo">1272</span> private static final
Comparator<FileStatus> FILE_STATUS_ID_COMPARATOR =<a name="line.1272"></a>
+<span class="sourceLineNo">1273</span> new Comparator<FileStatus>()
{<a name="line.1273"></a>
+<span class="sourceLineNo">1274</span> @Override<a name="line.1274"></a>
+<span class="sourceLineNo">1275</span> public int compare(FileStatus a,
FileStatus b) {<a name="line.1275"></a>
+<span class="sourceLineNo">1276</span> final long aId =
getLogIdFromName(a.getPath().getName());<a name="line.1276"></a>
+<span class="sourceLineNo">1277</span> final long bId =
getLogIdFromName(b.getPath().getName());<a name="line.1277"></a>
+<span class="sourceLineNo">1278</span> return Long.compare(aId, bId);<a
name="line.1278"></a>
+<span class="sourceLineNo">1279</span> }<a name="line.1279"></a>
+<span class="sourceLineNo">1280</span> };<a name="line.1280"></a>
+<span class="sourceLineNo">1281</span><a name="line.1281"></a>
+<span class="sourceLineNo">1282</span> private FileStatus[] getLogFiles()
throws IOException {<a name="line.1282"></a>
+<span class="sourceLineNo">1283</span> try {<a name="line.1283"></a>
+<span class="sourceLineNo">1284</span> FileStatus[] files =
fs.listStatus(walDir, WALS_PATH_FILTER);<a name="line.1284"></a>
+<span class="sourceLineNo">1285</span> Arrays.sort(files,
FILE_STATUS_ID_COMPARATOR);<a name="line.1285"></a>
+<span class="sourceLineNo">1286</span> return files;<a
name="line.1286"></a>
+<span class="sourceLineNo">1287</span> } catch (FileNotFoundException e)
{<a name="line.1287"></a>
+<span class="sourceLineNo">1288</span> LOG.warn("Log directory not found:
" + e.getMessage());<a name="line.1288"></a>
+<span class="sourceLineNo">1289</span> return null;<a
name="line.1289"></a>
+<span class="sourceLineNo">1290</span> }<a name="line.1290"></a>
+<span class="sourceLineNo">1291</span> }<a name="line.1291"></a>
+<span class="sourceLineNo">1292</span><a name="line.1292"></a>
+<span class="sourceLineNo">1293</span> /**<a name="line.1293"></a>
+<span class="sourceLineNo">1294</span> * Make sure that the file set are
gotten by calling {@link #getLogFiles()}, where we will sort<a
name="line.1294"></a>
+<span class="sourceLineNo">1295</span> * the file set by log id.<a
name="line.1295"></a>
+<span class="sourceLineNo">1296</span> * @return Max-LogID of the specified
log file set<a name="line.1296"></a>
+<span class="sourceLineNo">1297</span> */<a name="line.1297"></a>
+<span class="sourceLineNo">1298</span> private static long
getMaxLogId(FileStatus[] logFiles) {<a name="line.1298"></a>
+<span class="sourceLineNo">1299</span> if (logFiles == null ||
logFiles.length == 0) {<a name="line.1299"></a>
+<span class="sourceLineNo">1300</span> return 0L;<a name="line.1300"></a>
+<span class="sourceLineNo">1301</span> }<a name="line.1301"></a>
+<span class="sourceLineNo">1302</span> return
getLogIdFromName(logFiles[logFiles.length - 1].getPath().getName());<a
name="line.1302"></a>
+<span class="sourceLineNo">1303</span> }<a name="line.1303"></a>
+<span class="sourceLineNo">1304</span><a name="line.1304"></a>
+<span class="sourceLineNo">1305</span> /**<a name="line.1305"></a>
+<span class="sourceLineNo">1306</span> * Make sure that the file set are
gotten by calling {@link #getLogFiles()}, where we will sort<a
name="line.1306"></a>
+<span class="sourceLineNo">1307</span> * the file set by log id.<a
name="line.1307"></a>
+<span class="sourceLineNo">1308</span> * @return Max-LogID of the specified
log file set<a name="line.1308"></a>
+<span class="sourceLineNo">1309</span> */<a name="line.1309"></a>
+<span class="sourceLineNo">1310</span> private long initOldLogs(FileStatus[]
logFiles) throws IOException {<a name="line.1310"></a>
+<span class="sourceLineNo">1311</span> if (logFiles == null ||
logFiles.length == 0) {<a name="line.1311"></a>
+<span class="sourceLineNo">1312</span> return 0L;<a name="line.1312"></a>
+<span class="sourceLineNo">1313</span> }<a name="line.1313"></a>
+<span class="sourceLineNo">1314</span> long maxLogId = 0;<a
name="line.1314"></a>
+<span class="sourceLineNo">1315</span> for (int i = 0; i <
logFiles.length; ++i) {<a name="line.1315"></a>
+<span class="sourceLineNo">1316</span> final Path logPath =
logFiles[i].getPath();<a name="line.1316"></a>
+<span class="sourceLineNo">1317</span> leaseRecovery.recoverFileLease(fs,
logPath);<a name="line.1317"></a>
+<span class="sourceLineNo">1318</span> if (!isRunning()) {<a
name="line.1318"></a>
+<span class="sourceLineNo">1319</span> throw new IOException("wal
aborting");<a name="line.1319"></a>
+<span class="sourceLineNo">1320</span> }<a name="line.1320"></a>
+<span class="sourceLineNo">1321</span><a name="line.1321"></a>
+<span class="sourceLineNo">1322</span> maxLogId = Math.max(maxLogId,
getLogIdFromName(logPath.getName()));<a name="line.1322"></a>
+<span class="sourceLineNo">1323</span> ProcedureWALFile log =
initOldLog(logFiles[i], this.walArchiveDir);<a name="line.1323"></a>
+<span class="sourceLineNo">1324</span> if (log != null) {<a
name="line.1324"></a>
+<span class="sourceLineNo">1325</span> this.logs.add(log);<a
name="line.1325"></a>
+<span class="sourceLineNo">1326</span> }<a name="line.1326"></a>
+<span class="sourceLineNo">1327</span> }<a name="line.1327"></a>
+<span class="sourceLineNo">1328</span> initTrackerFromOldLogs();<a
name="line.1328"></a>
+<span class="sourceLineNo">1329</span> return maxLogId;<a
name="line.1329"></a>
+<span class="sourceLineNo">1330</span> }<a name="line.1330"></a>
+<span class="sourceLineNo">1331</span><a name="line.1331"></a>
+<span class="sourceLineNo">1332</span> /**<a name="line.1332"></a>
+<span class="sourceLineNo">1333</span> * If last log's tracker is not null,
use it as {@link #storeTracker}. Otherwise, set storeTracker<a
name="line.1333"></a>
+<span class="sourceLineNo">1334</span> * as partial, and let {@link
ProcedureWALFormatReader} rebuild it using entries in the log.<a
name="line.1334"></a>
+<span class="sourceLineNo">1335</span> */<a name="line.1335"></a>
+<span class="sourceLineNo">1336</span> private void initTrackerFromOldLogs()
{<a name="line.1336"></a>
+<span class="sourceLineNo">1337</span> if (logs.isEmpty() || !isRunning())
{<a name="line.1337"></a>
+<span class="sourceLineNo">1338</span> return;<a name="line.1338"></a>
+<span class="sourceLineNo">1339</span> }<a name="line.1339"></a>
+<span class="sourceLineNo">1340</span> ProcedureWALFile log =
logs.getLast();<a name="line.1340"></a>
+<span class="sourceLineNo">1341</span> if (!log.getTracker().isPartial())
{<a name="line.1341"></a>
+<span class="sourceLineNo">1342</span>
storeTracker.resetTo(log.getTracker());<a name="line.1342"></a>
+<span class="sourceLineNo">1343</span> } else {<a name="line.1343"></a>
+<span class="sourceLineNo">1344</span> storeTracker.reset();<a
name="line.1344"></a>
+<span class="sourceLineNo">1345</span>
storeTracker.setPartialFlag(true);<a name="line.1345"></a>
+<span class="sourceLineNo">1346</span> }<a name="line.1346"></a>
+<span class="sourceLineNo">1347</span> }<a name="line.1347"></a>
+<span class="sourceLineNo">1348</span><a name="line.1348"></a>
+<span class="sourceLineNo">1349</span> /**<a name="line.1349"></a>
+<span class="sourceLineNo">1350</span> * Loads given log file and it's
tracker.<a name="line.1350"></a>
+<span class="sourceLineNo">1351</span> */<a name="line.1351"></a>
+<span class="sourceLineNo">1352</span> private ProcedureWALFile
initOldLog(final FileStatus logFile, final Path walArchiveDir)<a
name="line.1352"></a>
+<span class="sourceLineNo">1353</span> throws IOException {<a
name="line.1353"></a>
+<span class="sourceLineNo">1354</span> final ProcedureWALFile log = new
ProcedureWALFile(fs, logFile);<a name="line.1354"></a>
+<span class="sourceLineNo">1355</span> if (logFile.getLen() == 0) {<a
name="line.1355"></a>
+<span class="sourceLineNo">1356</span> LOG.warn("Remove uninitialized
log: {}", logFile);<a name="line.1356"></a>
+<span class="sourceLineNo">1357</span> log.removeFile(walArchiveDir);<a
name="line.1357"></a>
+<span class="sourceLineNo">1358</span> return null;<a
name="line.1358"></a>
+<span class="sourceLineNo">1359</span> }<a name="line.1359"></a>
+<span class="sourceLineNo">1360</span> LOG.debug("Opening Pv2 {}",
logFile);<a name="line.1360"></a>
+<span class="sourceLineNo">1361</span> try {<a name="line.1361"></a>
+<span class="sourceLineNo">1362</span> log.open();<a name="line.1362"></a>
+<span class="sourceLineNo">1363</span> } catch
(ProcedureWALFormat.InvalidWALDataException e) {<a name="line.1363"></a>
+<span class="sourceLineNo">1364</span> LOG.warn("Remove uninitialized
log: {}", logFile, e);<a name="line.1364"></a>
+<span class="sourceLineNo">1365</span> log.removeFile(walArchiveDir);<a
name="line.1365"></a>
+<span class="sourceLineNo">1366</span> return null;<a
name="line.1366"></a>
+<span class="sourceLineNo">1367</span> } catch (IOException e) {<a
name="line.1367"></a>
+<span class="sourceLineNo">1368</span> String msg = "Unable to read state
log: " + logFile;<a name="line.1368"></a>
+<span class="sourceLineNo">1369</span> LOG.error(msg, e);<a
name="line.1369"></a>
+<span class="sourceLineNo">1370</span> throw new IOException(msg, e);<a
name="line.1370"></a>
+<span class="sourceLineNo">1371</span> }<a name="line.1371"></a>
+<span class="sourceLineNo">1372</span><a name="line.1372"></a>
+<span class="sourceLineNo">1373</span> try {<a name="line.1373"></a>
+<span class="sourceLineNo">1374</span> log.readTracker();<a
name="line.1374"></a>
+<span class="sourceLineNo">1375</span> } catch (IOException e) {<a
name="line.1375"></a>
+<span class="sourceLineNo">1376</span> log.getTracker().reset();<a
name="line.1376"></a>
+<span class="sourceLineNo">1377</span>
log.getTracker().setPartialFlag(true);<a name="line.1377"></a>
+<span class="sourceLineNo">1378</span> LOG.warn("Unable to read tracker
for {}", log, e);<a name="line.1378"></a>
+<span class="sourceLineNo">1379</span> }<a name="line.1379"></a>
+<span class="sourceLineNo">1380</span><a name="line.1380"></a>
+<span class="sourceLineNo">1381</span> log.close();<a name="line.1381"></a>
+<span class="sourceLineNo">1382</span> return log;<a name="line.1382"></a>
+<span class="sourceLineNo">1383</span> }<a name="line.1383"></a>
+<span class="sourceLineNo">1384</span><a name="line.1384"></a>
+<span class="sourceLineNo">1385</span> /**<a name="line.1385"></a>
+<span class="sourceLineNo">1386</span> * Parses a directory of WALs building
up ProcedureState.<a name="line.1386"></a>
+<span class="sourceLineNo">1387</span> * For testing parse and profiling.<a
name="line.1387"></a>
+<span class="sourceLineNo">1388</span> * @param args Include pointer to
directory of WAL files for a store instance to parse & load.<a
name="line.1388"></a>
+<span class="sourceLineNo">1389</span> */<a name="line.1389"></a>
+<span class="sourceLineNo">1390</span> public static void main(String []
args) throws IOException {<a name="line.1390"></a>
+<span class="sourceLineNo">1391</span> Configuration conf =
HBaseConfiguration.create();<a name="line.1391"></a>
+<span class="sourceLineNo">1392</span> if (args == null || args.length !=
1) {<a name="line.1392"></a>
+<span class="sourceLineNo">1393</span> System.out.println("ERROR: Empty
arguments list; pass path to MASTERPROCWALS_DIR.");<a name="line.1393"></a>
+<span class="sourceLineNo">1394</span> System.out.println("Usage:
WALProcedureStore MASTERPROCWALS_DIR");<a name="line.1394"></a>
+<span class="sourceLineNo">1395</span> System.exit(-1);<a
name="line.1395"></a>
+<span class="sourceLineNo">1396</span> }<a name="line.1396"></a>
+<span class="sourceLineNo">1397</span> WALProcedureStore store = new
WALProcedureStore(conf, new Path(args[0]), null,<a name="line.1397"></a>
+<span class="sourceLineNo">1398</span> new
WALProcedureStore.LeaseRecovery() {<a name="line.1398"></a>
+<span class="sourceLineNo">1399</span> @Override<a name="line.1399"></a>
+<span class="sourceLineNo">1400</span> public void
recoverFileLease(FileSystem fs, Path path) throws IOException {<a
name="line.1400"></a>
+<span class="sourceLineNo">1401</span> // no-op<a
name="line.1401"></a>
+<span class="sourceLineNo">1402</span> }<a name="line.1402"></a>
+<span class="sourceLineNo">1403</span> });<a name="line.1403"></a>
+<span class="sourceLineNo">1404</span> try {<a name="line.1404"></a>
+<span class="sourceLineNo">1405</span> store.start(16);<a
name="line.1405"></a>
+<span class="sourceLineNo">1406</span> ProcedureExecutor<?> pe =
new ProcedureExecutor<>(conf, new Object()/*Pass anything*/, store);<a
name="line.1406"></a>
+<span class="sourceLineNo">1407</span> pe.init(1, true);<a
name="line.1407"></a>
+<span class="sourceLineNo">1408</span> } finally {<a name="line.1408"></a>
+<span class="sourceLineNo">1409</span> store.stop(true);<a
name="line.1409"></a>
+<span class="sourceLineNo">1410</span> }<a name="line.1410"></a>
+<span class="sourceLineNo">1411</span> }<a name="line.1411"></a>
+<span class="sourceLineNo">1412</span>}<a name="line.1412"></a>