001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.procedure2.store.wal;
019
020import java.io.IOException;
021import org.apache.hadoop.fs.FSDataInputStream;
022import org.apache.hadoop.fs.FileStatus;
023import org.apache.hadoop.fs.FileSystem;
024import org.apache.hadoop.fs.Path;
025import org.apache.yetus.audience.InterfaceAudience;
026import org.slf4j.Logger;
027import org.slf4j.LoggerFactory;
028
029import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos;
030import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureWALHeader;
031import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureWALTrailer;
032
033/**
034 * Describes a WAL File
035 * @deprecated Since 2.3.0, will be removed in 4.0.0. Keep here only for rolling upgrading, now we
036 *             use the new region based procedure store.
037 */
038@Deprecated
039@InterfaceAudience.Private
040class ProcedureWALFile implements Comparable<ProcedureWALFile> {
041  private static final Logger LOG = LoggerFactory.getLogger(ProcedureWALFile.class);
042
043  private ProcedureWALHeader header;
044  private FSDataInputStream stream;
045  private FileSystem fs;
046  private Path logFile;
047  private long startPos;
048  private long minProcId;
049  private long maxProcId;
050  private long logSize;
051  private long timestamp;
052
053  public ProcedureStoreTracker getTracker() {
054    return tracker;
055  }
056
057  private final ProcedureStoreTracker tracker = new ProcedureStoreTracker();
058
059  public ProcedureWALFile(final FileSystem fs, final FileStatus logStatus) {
060    this.fs = fs;
061    this.logFile = logStatus.getPath();
062    this.logSize = logStatus.getLen();
063    this.timestamp = logStatus.getModificationTime();
064    tracker.setPartialFlag(true);
065  }
066
067  public ProcedureWALFile(FileSystem fs, Path logFile, ProcedureWALHeader header,
068      long startPos, long timestamp) {
069    this.fs = fs;
070    this.header = header;
071    this.logFile = logFile;
072    this.startPos = startPos;
073    this.logSize = startPos;
074    this.timestamp = timestamp;
075    tracker.setPartialFlag(true);
076  }
077
078  public void open() throws IOException {
079    if (stream == null) {
080      stream = fs.open(logFile);
081    }
082
083    if (header == null) {
084      header = ProcedureWALFormat.readHeader(stream);
085      startPos = stream.getPos();
086    } else {
087      stream.seek(startPos);
088    }
089  }
090
091  public ProcedureWALTrailer readTrailer() throws IOException {
092    try {
093      return ProcedureWALFormat.readTrailer(stream, startPos, logSize);
094    } finally {
095      stream.seek(startPos);
096    }
097  }
098
099  public void readTracker() throws IOException {
100    ProcedureWALTrailer trailer = readTrailer();
101    try {
102      stream.seek(trailer.getTrackerPos());
103      final ProcedureProtos.ProcedureStoreTracker trackerProtoBuf =
104          ProcedureProtos.ProcedureStoreTracker.parseDelimitedFrom(stream);
105      tracker.resetToProto(trackerProtoBuf);
106    } finally {
107      stream.seek(startPos);
108    }
109  }
110
111  public void updateLocalTracker(ProcedureStoreTracker tracker) {
112    this.tracker.resetTo(tracker);
113  }
114
115  public void close() {
116    if (stream == null) {
117      return;
118    }
119
120    try {
121      stream.close();
122    } catch (IOException e) {
123      LOG.warn("unable to close the wal file: " + logFile, e);
124    } finally {
125      stream = null;
126    }
127  }
128
129  public FSDataInputStream getStream() {
130    return stream;
131  }
132
133  public ProcedureWALHeader getHeader() {
134    return header;
135  }
136
137  public long getTimestamp() {
138    return timestamp;
139  }
140
141  public boolean isCompacted() {
142    return header.getType() == ProcedureWALFormat.LOG_TYPE_COMPACTED;
143  }
144
145  public long getLogId() {
146    return header.getLogId();
147  }
148
149  public long getSize() {
150    return logSize;
151  }
152
153  /**
154   * Used to update in-progress log sizes. the FileStatus will report 0 otherwise.
155   */
156  void addToSize(long size) {
157    this.logSize += size;
158  }
159
160  public void removeFile(final Path walArchiveDir) throws IOException {
161    close();
162    boolean archived = false;
163    if (walArchiveDir != null) {
164      Path archivedFile = new Path(walArchiveDir, logFile.getName());
165      LOG.info("Archiving " + logFile + " to " + archivedFile);
166      if (!fs.rename(logFile, archivedFile)) {
167        LOG.warn("Failed archive of " + logFile + ", deleting");
168      } else {
169        archived = true;
170      }
171    }
172    if (!archived) {
173      if (!fs.delete(logFile, false)) {
174        LOG.warn("Failed delete of " + logFile);
175      }
176    }
177  }
178
179  public void setProcIds(long minId, long maxId) {
180    this.minProcId = minId;
181    this.maxProcId = maxId;
182  }
183
184  public long getMinProcId() {
185    return minProcId;
186  }
187
188  public long getMaxProcId() {
189    return maxProcId;
190  }
191
192  @Override
193  public int compareTo(final ProcedureWALFile other) {
194    long diff = header.getLogId() - other.header.getLogId();
195    return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
196  }
197
198  @Override
199  public boolean equals(Object o) {
200    if (this == o) {
201      return true;
202    }
203
204    if (!(o instanceof ProcedureWALFile)) {
205      return false;
206    }
207
208    return compareTo((ProcedureWALFile)o) == 0;
209  }
210
211  @Override
212  public int hashCode() {
213    return logFile.hashCode();
214  }
215
216  @Override
217  public String toString() {
218    return logFile.toString();
219  }
220}