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.backup.util; 019 020import java.io.IOException; 021import java.util.ArrayList; 022import java.util.List; 023import org.apache.hadoop.fs.Path; 024import org.apache.hadoop.hbase.Cell; 025import org.apache.hadoop.hbase.CellUtil; 026import org.apache.hadoop.hbase.TableName; 027import org.apache.hadoop.hbase.wal.WAL; 028import org.apache.hadoop.hbase.wal.WALEdit; 029import org.apache.hadoop.hbase.wal.WALKey; 030import org.apache.yetus.audience.InterfaceAudience; 031 032import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos; 033 034/** 035 * Processes bulk load files from Write-Ahead Log (WAL) entries. 036 * <p> 037 * Used by backup/restore and replication flows to discover HFiles referenced by bulk-load WALEdits. 038 * Returned {@link Path}s are constructed from the namespace/table/region/family/file components. 039 * </p> 040 */ 041@InterfaceAudience.Private 042public final class BulkLoadProcessor { 043 private BulkLoadProcessor() { 044 } 045 046 /** 047 * Extract bulk-load file {@link Path}s from a list of {@link WAL.Entry}. 048 * @param walEntries list of WAL entries. 049 * @return list of Paths in discovery order; empty list if none 050 * @throws IOException if descriptor parsing fails 051 */ 052 public static List<Path> processBulkLoadFiles(List<WAL.Entry> walEntries) throws IOException { 053 List<Path> bulkLoadFilePaths = new ArrayList<>(); 054 055 for (WAL.Entry entry : walEntries) { 056 bulkLoadFilePaths.addAll(processBulkLoadFiles(entry.getKey(), entry.getEdit())); 057 } 058 return bulkLoadFilePaths; 059 } 060 061 /** 062 * Extract bulk-load file {@link Path}s from a single WAL entry. 063 * @param key WALKey containing table information; if null returns empty list 064 * @param edit WALEdit to scan; if null returns empty list 065 * @return list of Paths referenced by bulk-load descriptor(s) in this edit; may be empty or 066 * contain duplicates 067 * @throws IOException if descriptor parsing fails 068 */ 069 public static List<Path> processBulkLoadFiles(WALKey key, WALEdit edit) throws IOException { 070 List<Path> bulkLoadFilePaths = new ArrayList<>(); 071 072 for (Cell cell : edit.getCells()) { 073 if (CellUtil.matchingQualifier(cell, WALEdit.BULK_LOAD)) { 074 TableName tableName = key.getTableName(); 075 String namespace = tableName.getNamespaceAsString(); 076 String table = tableName.getQualifierAsString(); 077 bulkLoadFilePaths.addAll(processBulkLoadDescriptor(cell, namespace, table)); 078 } 079 } 080 081 return bulkLoadFilePaths; 082 } 083 084 private static List<Path> processBulkLoadDescriptor(Cell cell, String namespace, String table) 085 throws IOException { 086 List<Path> bulkLoadFilePaths = new ArrayList<>(); 087 WALProtos.BulkLoadDescriptor bld = WALEdit.getBulkLoadDescriptor(cell); 088 089 if (bld == null || !bld.getReplicate() || bld.getEncodedRegionName() == null) { 090 return bulkLoadFilePaths; // Skip if not replicable 091 } 092 093 String regionName = bld.getEncodedRegionName().toStringUtf8(); 094 for (WALProtos.StoreDescriptor storeDescriptor : bld.getStoresList()) { 095 bulkLoadFilePaths 096 .addAll(processStoreDescriptor(storeDescriptor, namespace, table, regionName)); 097 } 098 099 return bulkLoadFilePaths; 100 } 101 102 private static List<Path> processStoreDescriptor(WALProtos.StoreDescriptor storeDescriptor, 103 String namespace, String table, String regionName) { 104 List<Path> paths = new ArrayList<>(); 105 String columnFamily = storeDescriptor.getFamilyName().toStringUtf8(); 106 107 for (String storeFile : storeDescriptor.getStoreFileList()) { 108 paths.add(new Path(namespace, 109 new Path(table, new Path(regionName, new Path(columnFamily, storeFile))))); 110 } 111 112 return paths; 113 } 114}