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; 019 020import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_ENABLE_CONTINUOUS_BACKUP; 021import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_PITR_BACKUP_PATH; 022import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_TABLE; 023import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_TABLE_MAPPING; 024import static org.apache.hadoop.hbase.backup.BackupRestoreConstants.OPTION_TO_DATETIME; 025 026import java.io.IOException; 027import java.util.ArrayList; 028import java.util.Arrays; 029import java.util.List; 030import java.util.stream.Collectors; 031import org.apache.hadoop.conf.Configuration; 032import org.apache.hadoop.fs.FileSystem; 033import org.apache.hadoop.fs.Path; 034import org.apache.hadoop.hbase.HBaseTestingUtil; 035import org.apache.hadoop.hbase.TableName; 036import org.apache.hadoop.hbase.client.Connection; 037import org.apache.hadoop.hbase.client.Table; 038import org.apache.hadoop.hbase.tool.BulkLoadHFiles; 039import org.apache.hadoop.hbase.tool.BulkLoadHFilesTool; 040import org.apache.hadoop.hbase.util.Bytes; 041import org.apache.hadoop.hbase.util.HFileTestUtil; 042import org.apache.yetus.audience.InterfaceAudience; 043import org.slf4j.Logger; 044import org.slf4j.LoggerFactory; 045 046@InterfaceAudience.Private 047public final class PITRTestUtil { 048 private static final Logger LOG = LoggerFactory.getLogger(PITRTestUtil.class); 049 private static final int DEFAULT_WAIT_FOR_REPLICATION_MS = 30_000; 050 051 private PITRTestUtil() { 052 // Utility class 053 } 054 055 public static String[] buildPITRArgs(TableName[] sourceTables, TableName[] targetTables, 056 long endTime, String backupRootDir) { 057 String sourceTableNames = 058 Arrays.stream(sourceTables).map(TableName::getNameAsString).collect(Collectors.joining(",")); 059 String targetTableNames = 060 Arrays.stream(targetTables).map(TableName::getNameAsString).collect(Collectors.joining(",")); 061 062 List<String> args = new ArrayList<>(); 063 args.add("-" + OPTION_TABLE); 064 args.add(sourceTableNames); 065 args.add("-" + OPTION_TABLE_MAPPING); 066 args.add(targetTableNames); 067 args.add("-" + OPTION_TO_DATETIME); 068 args.add(String.valueOf(endTime)); 069 070 if (backupRootDir != null) { 071 args.add("-" + OPTION_PITR_BACKUP_PATH); 072 args.add(backupRootDir); 073 } 074 075 return args.toArray(new String[0]); 076 } 077 078 public static String[] buildBackupArgs(String backupType, TableName[] tables, 079 boolean continuousEnabled, String backupRootDir) { 080 String tableNames = 081 Arrays.stream(tables).map(TableName::getNameAsString).collect(Collectors.joining(",")); 082 083 List<String> args = new ArrayList<>( 084 Arrays.asList("create", backupType, backupRootDir, "-" + OPTION_TABLE, tableNames)); 085 086 if (continuousEnabled) { 087 args.add("-" + OPTION_ENABLE_CONTINUOUS_BACKUP); 088 } 089 090 return args.toArray(new String[0]); 091 } 092 093 public static void loadRandomData(HBaseTestingUtil testUtil, TableName tableName, byte[] family, 094 int totalRows) throws IOException { 095 try (Table table = testUtil.getConnection().getTable(tableName)) { 096 testUtil.loadRandomRows(table, family, 32, totalRows); 097 } 098 } 099 100 public static void waitForReplication() { 101 try { 102 LOG.info("Waiting for replication to complete for {} ms", DEFAULT_WAIT_FOR_REPLICATION_MS); 103 Thread.sleep(DEFAULT_WAIT_FOR_REPLICATION_MS); 104 } catch (InterruptedException e) { 105 Thread.currentThread().interrupt(); 106 throw new RuntimeException("Interrupted while waiting for replication", e); 107 } 108 } 109 110 public static int getRowCount(HBaseTestingUtil testUtil, TableName tableName) throws IOException { 111 try (Table table = testUtil.getConnection().getTable(tableName)) { 112 return HBaseTestingUtil.countRows(table); 113 } 114 } 115 116 public static void generateHFiles(Path outputDir, Configuration conf, String cfName) 117 throws IOException { 118 String hFileName = "MyHFile"; 119 int numRows = 1000; 120 121 FileSystem fs = FileSystem.get(conf); 122 outputDir = outputDir.makeQualified(fs.getUri(), fs.getWorkingDirectory()); 123 124 byte[] from = Bytes.toBytes(cfName + "begin"); 125 byte[] to = Bytes.toBytes(cfName + "end"); 126 127 Path familyDir = new Path(outputDir, cfName); 128 HFileTestUtil.createHFile(conf, fs, new Path(familyDir, hFileName), Bytes.toBytes(cfName), 129 Bytes.toBytes("qualifier"), from, to, numRows); 130 } 131 132 public static void bulkLoadHFiles(TableName tableName, Path inputDir, Connection conn, 133 Configuration conf) throws IOException { 134 conf.setBoolean(BulkLoadHFilesTool.BULK_LOAD_HFILES_BY_FAMILY, true); 135 136 try (Table table = conn.getTable(tableName)) { 137 BulkLoadHFiles loader = new BulkLoadHFilesTool(conf); 138 loader.bulkLoad(table.getName(), inputDir); 139 } finally { 140 conf.setBoolean(BulkLoadHFilesTool.BULK_LOAD_HFILES_BY_FAMILY, false); 141 } 142 } 143}