1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.regionserver.snapshot;
19
20 import java.util.List;
21 import java.util.concurrent.Callable;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.hadoop.classification.InterfaceAudience;
26 import org.apache.hadoop.classification.InterfaceStability;
27 import org.apache.hadoop.hbase.errorhandling.ForeignException;
28 import org.apache.hadoop.hbase.errorhandling.ForeignExceptionDispatcher;
29 import org.apache.hadoop.hbase.procedure.ProcedureMember;
30 import org.apache.hadoop.hbase.procedure.Subprocedure;
31 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
32 import org.apache.hadoop.hbase.regionserver.HRegion;
33 import org.apache.hadoop.hbase.regionserver.snapshot.RegionServerSnapshotManager.SnapshotSubprocedurePool;
34 import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
35
36
37
38
39
40
41
42
43 @InterfaceAudience.Private
44 @InterfaceStability.Unstable
45 public class FlushSnapshotSubprocedure extends Subprocedure {
46 private static final Log LOG = LogFactory.getLog(FlushSnapshotSubprocedure.class);
47
48 private final List<HRegion> regions;
49 private final SnapshotDescription snapshot;
50 private final SnapshotSubprocedurePool taskManager;
51
52 private boolean snapshotSkipFlush = false;
53
54 public FlushSnapshotSubprocedure(ProcedureMember member,
55 ForeignExceptionDispatcher errorListener, long wakeFrequency, long timeout,
56 List<HRegion> regions, SnapshotDescription snapshot,
57 SnapshotSubprocedurePool taskManager) {
58 super(member, snapshot.getName(), errorListener, wakeFrequency, timeout);
59 this.snapshot = snapshot;
60 if (this.snapshot.getType() == SnapshotDescription.Type.SKIPFLUSH) {
61 snapshotSkipFlush = true;
62 }
63
64 this.regions = regions;
65 this.taskManager = taskManager;
66 }
67
68
69
70
71 private class RegionSnapshotTask implements Callable<Void> {
72 HRegion region;
73 RegionSnapshotTask(HRegion region) {
74 this.region = region;
75 }
76
77 @Override
78 public Void call() throws Exception {
79
80
81
82
83
84 LOG.debug("Starting region operation on " + region);
85 region.startRegionOperation();
86 try {
87 if (snapshotSkipFlush) {
88
89
90
91
92
93
94
95 LOG.debug("take snapshot without flush memstore first");
96 } else {
97 LOG.debug("Flush Snapshotting region " + region.toString() + " started...");
98 region.flushcache();
99 }
100 region.addRegionToSnapshot(snapshot, monitor);
101 if (snapshotSkipFlush) {
102 LOG.debug("... SkipFlush Snapshotting region " + region.toString() + " completed.");
103 } else {
104 LOG.debug("... Flush Snapshotting region " + region.toString() + " completed.");
105 }
106 } finally {
107 LOG.debug("Closing region operation on " + region);
108 region.closeRegionOperation();
109 }
110 return null;
111 }
112 }
113
114 private void flushSnapshot() throws ForeignException {
115 if (regions.isEmpty()) {
116
117 return;
118 }
119
120 monitor.rethrowException();
121
122
123 if (taskManager.hasTasks()) {
124 throw new IllegalStateException("Attempting to take snapshot "
125 + SnapshotDescriptionUtils.toString(snapshot)
126 + " but we currently have outstanding tasks");
127 }
128
129
130 for (HRegion region : regions) {
131
132 taskManager.submitTask(new RegionSnapshotTask(region));
133 monitor.rethrowException();
134 }
135
136
137 LOG.debug("Flush Snapshot Tasks submitted for " + regions.size() + " regions");
138 try {
139 taskManager.waitForOutstandingTasks();
140 } catch (InterruptedException e) {
141 throw new ForeignException(getMemberName(), e);
142 }
143 }
144
145
146
147
148 @Override
149 public void acquireBarrier() throws ForeignException {
150
151 }
152
153
154
155
156 @Override
157 public void insideBarrier() throws ForeignException {
158 flushSnapshot();
159 }
160
161
162
163
164 @Override
165 public void cleanup(Exception e) {
166 LOG.info("Aborting all online FLUSH snapshot subprocedure task threads for '"
167 + snapshot.getName() + "' due to error", e);
168 try {
169 taskManager.cancelTasks();
170 } catch (InterruptedException e1) {
171 Thread.currentThread().interrupt();
172 }
173 }
174
175
176
177
178 public void releaseBarrier() {
179
180 }
181
182 }