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.regionserver.wal; 019 020import java.io.IOException; 021import org.apache.hadoop.conf.Configuration; 022import org.apache.hadoop.fs.FileSystem; 023import org.apache.hadoop.fs.Path; 024import org.apache.hadoop.hbase.ServerName; 025import org.apache.hadoop.hbase.namequeues.NamedQueueRecorder; 026import org.apache.hadoop.hbase.namequeues.WALEventTrackerPayload; 027import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 028import org.apache.yetus.audience.InterfaceAudience; 029 030@InterfaceAudience.Private 031public class WALEventTrackerListener implements WALActionsListener { 032 private final Configuration conf; 033 private final NamedQueueRecorder namedQueueRecorder; 034 private final String serverName; 035 036 public enum WalState { 037 ROLLING, 038 ROLLED, 039 ACTIVE 040 } 041 042 public WALEventTrackerListener(Configuration conf, NamedQueueRecorder namedQueueRecorder, 043 ServerName serverName) { 044 this.conf = conf; 045 this.namedQueueRecorder = namedQueueRecorder; 046 this.serverName = serverName.getHostname(); 047 } 048 049 @Override 050 public void preLogRoll(Path oldPath, Path newPath) { 051 if (oldPath != null) { 052 // oldPath can be null for first wal 053 // Just persist the last component of path not the whole walName which includes filesystem 054 // scheme, walDir. 055 WALEventTrackerPayload payloadForOldPath = 056 getPayload(oldPath.getName(), WalState.ROLLING.name(), 0L); 057 this.namedQueueRecorder.addRecord(payloadForOldPath); 058 } 059 } 060 061 @Override 062 public void postLogRoll(Path oldPath, Path newPath) { 063 // Create 2 entries entry in RingBuffer. 064 // 1. Change state to Rolled for oldPath 065 // 2. Change state to Active for newPath. 066 if (oldPath != null) { 067 // oldPath can be null for first wal 068 // Just persist the last component of path not the whole walName which includes filesystem 069 // scheme, walDir. 070 071 long fileLength = 0L; 072 try { 073 FileSystem fs = oldPath.getFileSystem(this.conf); 074 fileLength = fs.getFileStatus(oldPath).getLen(); 075 } catch (IOException ioe) { 076 // Saving wal length is best effort. In case of any exception just ignore. 077 } 078 WALEventTrackerPayload payloadForOldPath = 079 getPayload(oldPath.getName(), WalState.ROLLED.name(), fileLength); 080 this.namedQueueRecorder.addRecord(payloadForOldPath); 081 } 082 083 WALEventTrackerPayload payloadForNewPath = 084 getPayload(newPath.getName(), WalState.ACTIVE.name(), 0L); 085 this.namedQueueRecorder.addRecord(payloadForNewPath); 086 } 087 088 private WALEventTrackerPayload getPayload(String path, String state, long walLength) { 089 long timestamp = EnvironmentEdgeManager.currentTime(); 090 WALEventTrackerPayload payload = 091 new WALEventTrackerPayload(serverName, path, timestamp, state, walLength); 092 return payload; 093 } 094}