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.junit.Assert.assertFalse; 021import static org.junit.Assert.assertTrue; 022 023import java.io.IOException; 024import java.util.List; 025import org.apache.commons.lang3.StringUtils; 026import org.apache.hadoop.hbase.HBaseClassTestRule; 027import org.apache.hadoop.hbase.TableName; 028import org.apache.hadoop.hbase.backup.util.BackupUtils; 029import org.apache.hadoop.hbase.client.Admin; 030import org.apache.hadoop.hbase.client.Table; 031import org.apache.hadoop.hbase.testclassification.LargeTests; 032import org.apache.hadoop.util.ToolRunner; 033import org.junit.ClassRule; 034import org.junit.Test; 035import org.junit.experimental.categories.Category; 036import org.slf4j.Logger; 037import org.slf4j.LoggerFactory; 038 039import org.apache.hbase.thirdparty.com.google.common.collect.Lists; 040 041@Category(LargeTests.class) 042public class TestFullRestore extends TestBackupBase { 043 044 @ClassRule 045 public static final HBaseClassTestRule CLASS_RULE = 046 HBaseClassTestRule.forClass(TestFullRestore.class); 047 048 private static final Logger LOG = LoggerFactory.getLogger(TestFullRestore.class); 049 050 /** 051 * Verify that a single table is restored to a new table. 052 * @throws Exception if doing the backup, restoring it or an operation on the tables fails 053 */ 054 @Test 055 public void testFullRestoreSingle() throws Exception { 056 LOG.info("test full restore on a single table empty table"); 057 058 List<TableName> tables = Lists.newArrayList(table1); 059 String backupId = fullTableBackup(tables); 060 assertTrue(checkSucceeded(backupId)); 061 062 LOG.info("backup complete"); 063 064 TableName[] tableset = new TableName[] { table1 }; 065 TableName[] tablemap = new TableName[] { table1_restore }; 066 BackupAdmin client = getBackupAdmin(); 067 client.restore(BackupUtils.createRestoreRequest(BACKUP_ROOT_DIR, backupId, false, tableset, 068 tablemap, false)); 069 Admin hba = TEST_UTIL.getAdmin(); 070 assertTrue(hba.tableExists(table1_restore)); 071 TEST_UTIL.deleteTable(table1_restore); 072 hba.close(); 073 } 074 075 @Test 076 public void testFullRestoreSingleWithRegion() throws Exception { 077 LOG.info("test full restore on a single table empty table that has a region"); 078 079 // This test creates its own table so other tests are not affected (we adjust it in this test) 080 TableName tableName = TableName.valueOf("table-full-restore-single-region"); 081 TEST_UTIL.createTable(tableName, famName); 082 083 Admin admin = TEST_UTIL.getAdmin(); 084 085 // Add & remove data to ensure a region is active, but functionally empty 086 Table table = TEST_UTIL.getConnection().getTable(tableName); 087 loadTable(table); 088 admin.flush(tableName); 089 TEST_UTIL.deleteTableData(tableName); 090 admin.flush(tableName); 091 092 TEST_UTIL.compact(tableName, true); 093 094 List<TableName> tables = Lists.newArrayList(tableName); 095 String backupId = fullTableBackup(tables); 096 assertTrue(checkSucceeded(backupId)); 097 098 LOG.info("backup complete"); 099 100 TEST_UTIL.deleteTable(tableName); 101 102 TableName[] tableset = new TableName[] { tableName }; 103 TableName[] tablemap = new TableName[] { tableName }; 104 BackupAdmin client = getBackupAdmin(); 105 client.restore(BackupUtils.createRestoreRequest(BACKUP_ROOT_DIR, backupId, false, tableset, 106 tablemap, false)); 107 assertTrue(admin.tableExists(tableName)); 108 TEST_UTIL.deleteTable(tableName); 109 admin.close(); 110 } 111 112 @Test 113 public void testFullRestoreSingleCommand() throws Exception { 114 LOG.info("test full restore on a single table empty table: command-line"); 115 116 List<TableName> tables = Lists.newArrayList(table1); 117 String backupId = fullTableBackup(tables); 118 LOG.info("backup complete"); 119 assertTrue(checkSucceeded(backupId)); 120 // restore <backup_root_path> <backup_id> <tables> [tableMapping] 121 String[] args = new String[] { BACKUP_ROOT_DIR, backupId, "-t", table1.getNameAsString(), "-m", 122 table1_restore.getNameAsString() }; 123 // Run backup 124 int ret = ToolRunner.run(conf1, new RestoreDriver(), args); 125 126 assertTrue(ret == 0); 127 Admin hba = TEST_UTIL.getAdmin(); 128 assertTrue(hba.tableExists(table1_restore)); 129 TEST_UTIL.deleteTable(table1_restore); 130 hba.close(); 131 } 132 133 @Test 134 public void testFullRestoreCheckCommand() throws Exception { 135 LOG.info("test full restore on a single table: command-line, check only"); 136 137 List<TableName> tables = Lists.newArrayList(table1); 138 String backupId = fullTableBackup(tables); 139 LOG.info("backup complete"); 140 assertTrue(checkSucceeded(backupId)); 141 // restore <backup_root_path> <backup_id> <tables> [tableMapping] 142 String[] args = new String[] { BACKUP_ROOT_DIR, backupId, "-t", table1.getNameAsString(), "-m", 143 table1_restore.getNameAsString(), "-c" }; 144 // Run backup 145 int ret = ToolRunner.run(conf1, new RestoreDriver(), args); 146 assertTrue(ret == 0); 147 // Verify that table has not been restored 148 Admin hba = TEST_UTIL.getAdmin(); 149 assertFalse(hba.tableExists(table1_restore)); 150 } 151 152 /** 153 * Verify that multiple tables are restored to new tables. 154 * @throws Exception if doing the backup, restoring it or an operation on the tables fails 155 */ 156 @Test 157 public void testFullRestoreMultiple() throws Exception { 158 LOG.info("create full backup image on multiple tables"); 159 List<TableName> tables = Lists.newArrayList(table2, table3); 160 String backupId = fullTableBackup(tables); 161 assertTrue(checkSucceeded(backupId)); 162 163 TableName[] restore_tableset = new TableName[] { table2, table3 }; 164 TableName[] tablemap = new TableName[] { table2_restore, table3_restore }; 165 BackupAdmin client = getBackupAdmin(); 166 client.restore(BackupUtils.createRestoreRequest(BACKUP_ROOT_DIR, backupId, false, 167 restore_tableset, tablemap, false)); 168 Admin hba = TEST_UTIL.getAdmin(); 169 assertTrue(hba.tableExists(table2_restore)); 170 assertTrue(hba.tableExists(table3_restore)); 171 TEST_UTIL.deleteTable(table2_restore); 172 TEST_UTIL.deleteTable(table3_restore); 173 hba.close(); 174 } 175 176 /** 177 * Verify that multiple tables are restored to new tables. 178 * @throws Exception if doing the backup, restoring it or an operation on the tables fails 179 */ 180 @Test 181 public void testFullRestoreMultipleCommand() throws Exception { 182 LOG.info("create full backup image on multiple tables: command-line"); 183 List<TableName> tables = Lists.newArrayList(table2, table3); 184 String backupId = fullTableBackup(tables); 185 assertTrue(checkSucceeded(backupId)); 186 187 TableName[] restore_tableset = new TableName[] { table2, table3 }; 188 TableName[] tablemap = new TableName[] { table2_restore, table3_restore }; 189 190 // restore <backup_root_path> <backup_id> <tables> [tableMapping] 191 String[] args = new String[] { BACKUP_ROOT_DIR, backupId, "-t", 192 StringUtils.join(restore_tableset, ","), "-m", StringUtils.join(tablemap, ",") }; 193 // Run backup 194 int ret = ToolRunner.run(conf1, new RestoreDriver(), args); 195 196 assertTrue(ret == 0); 197 Admin hba = TEST_UTIL.getAdmin(); 198 assertTrue(hba.tableExists(table2_restore)); 199 assertTrue(hba.tableExists(table3_restore)); 200 TEST_UTIL.deleteTable(table2_restore); 201 TEST_UTIL.deleteTable(table3_restore); 202 hba.close(); 203 } 204 205 /** 206 * Verify that a single table is restored using overwrite. 207 * @throws Exception if doing the backup or restoring it fails 208 */ 209 @Test 210 public void testFullRestoreSingleOverwrite() throws Exception { 211 LOG.info("test full restore on a single table empty table"); 212 List<TableName> tables = Lists.newArrayList(table1); 213 String backupId = fullTableBackup(tables); 214 assertTrue(checkSucceeded(backupId)); 215 216 LOG.info("backup complete"); 217 218 TableName[] tableset = new TableName[] { table1 }; 219 BackupAdmin client = getBackupAdmin(); 220 client.restore( 221 BackupUtils.createRestoreRequest(BACKUP_ROOT_DIR, backupId, false, tableset, null, true)); 222 } 223 224 /** 225 * Verify that a single table is restored using overwrite. 226 * @throws Exception if doing the backup or an operation on the tables fails 227 */ 228 @Test 229 public void testFullRestoreSingleOverwriteCommand() throws Exception { 230 LOG.info("test full restore on a single table empty table: command-line"); 231 List<TableName> tables = Lists.newArrayList(table1); 232 String backupId = fullTableBackup(tables); 233 assertTrue(checkSucceeded(backupId)); 234 LOG.info("backup complete"); 235 TableName[] tableset = new TableName[] { table1 }; 236 // restore <backup_root_path> <backup_id> <tables> [tableMapping] 237 String[] args = 238 new String[] { BACKUP_ROOT_DIR, backupId, "-t", StringUtils.join(tableset, ","), "-o" }; 239 // Run restore 240 int ret = ToolRunner.run(conf1, new RestoreDriver(), args); 241 assertTrue(ret == 0); 242 243 Admin hba = TEST_UTIL.getAdmin(); 244 assertTrue(hba.tableExists(table1)); 245 hba.close(); 246 } 247 248 /** 249 * Verify that multiple tables are restored to new tables using overwrite. 250 * @throws Exception if doing the backup or restoring it fails 251 */ 252 @Test 253 public void testFullRestoreMultipleOverwrite() throws Exception { 254 LOG.info("create full backup image on multiple tables"); 255 256 List<TableName> tables = Lists.newArrayList(table2, table3); 257 String backupId = fullTableBackup(tables); 258 assertTrue(checkSucceeded(backupId)); 259 260 TableName[] restore_tableset = new TableName[] { table2, table3 }; 261 BackupAdmin client = getBackupAdmin(); 262 client.restore(BackupUtils.createRestoreRequest(BACKUP_ROOT_DIR, backupId, false, 263 restore_tableset, null, true)); 264 } 265 266 /** 267 * Verify that multiple tables are restored to new tables using overwrite. 268 * @throws Exception if doing the backup or an operation on the tables fails 269 */ 270 @Test 271 public void testFullRestoreMultipleOverwriteCommand() throws Exception { 272 LOG.info("create full backup image on multiple tables: command-line"); 273 274 List<TableName> tables = Lists.newArrayList(table2, table3); 275 String backupId = fullTableBackup(tables); 276 assertTrue(checkSucceeded(backupId)); 277 278 TableName[] restore_tableset = new TableName[] { table2, table3 }; 279 // restore <backup_root_path> <backup_id> <tables> [tableMapping] 280 String[] args = new String[] { BACKUP_ROOT_DIR, backupId, "-t", 281 StringUtils.join(restore_tableset, ","), "-o" }; 282 // Run backup 283 int ret = ToolRunner.run(conf1, new RestoreDriver(), args); 284 285 assertTrue(ret == 0); 286 Admin hba = TEST_UTIL.getAdmin(); 287 assertTrue(hba.tableExists(table2)); 288 assertTrue(hba.tableExists(table3)); 289 hba.close(); 290 } 291 292 /** 293 * Verify that restore fails on a single table that does not exist. 294 * @throws Exception if doing the backup or restoring it fails 295 */ 296 @Test(expected = IOException.class) 297 public void testFullRestoreSingleDNE() throws Exception { 298 LOG.info("test restore fails on a single table that does not exist"); 299 List<TableName> tables = Lists.newArrayList(table1); 300 String backupId = fullTableBackup(tables); 301 assertTrue(checkSucceeded(backupId)); 302 303 LOG.info("backup complete"); 304 305 TableName[] tableset = new TableName[] { TableName.valueOf("faketable") }; 306 TableName[] tablemap = new TableName[] { table1_restore }; 307 BackupAdmin client = getBackupAdmin(); 308 client.restore(BackupUtils.createRestoreRequest(BACKUP_ROOT_DIR, backupId, false, tableset, 309 tablemap, false)); 310 } 311 312 /** 313 * Verify that restore fails on a single table that does not exist. 314 * @throws Exception if doing the backup or restoring it fails 315 */ 316 @Test 317 public void testFullRestoreSingleDNECommand() throws Exception { 318 LOG.info("test restore fails on a single table that does not exist: command-line"); 319 List<TableName> tables = Lists.newArrayList(table1); 320 String backupId = fullTableBackup(tables); 321 assertTrue(checkSucceeded(backupId)); 322 323 LOG.info("backup complete"); 324 325 TableName[] tableset = new TableName[] { TableName.valueOf("faketable") }; 326 TableName[] tablemap = new TableName[] { table1_restore }; 327 String[] args = new String[] { BACKUP_ROOT_DIR, backupId, StringUtils.join(tableset, ","), "-m", 328 StringUtils.join(tablemap, ",") }; 329 // Run restore 330 int ret = ToolRunner.run(conf1, new RestoreDriver(), args); 331 assertTrue(ret != 0); 332 } 333 334 /** 335 * Verify that restore fails on multiple tables that do not exist. 336 * @throws Exception if doing the backup or restoring it fails 337 */ 338 @Test(expected = IOException.class) 339 public void testFullRestoreMultipleDNE() throws Exception { 340 LOG.info("test restore fails on multiple tables that do not exist"); 341 342 List<TableName> tables = Lists.newArrayList(table2, table3); 343 String backupId = fullTableBackup(tables); 344 assertTrue(checkSucceeded(backupId)); 345 346 TableName[] restore_tableset = 347 new TableName[] { TableName.valueOf("faketable1"), TableName.valueOf("faketable2") }; 348 TableName[] tablemap = new TableName[] { table2_restore, table3_restore }; 349 BackupAdmin client = getBackupAdmin(); 350 client.restore(BackupUtils.createRestoreRequest(BACKUP_ROOT_DIR, backupId, false, 351 restore_tableset, tablemap, false)); 352 } 353 354 /** 355 * Verify that restore fails on multiple tables that do not exist. 356 * @throws Exception if doing the backup or restoring it fails 357 */ 358 @Test 359 public void testFullRestoreMultipleDNECommand() throws Exception { 360 LOG.info("test restore fails on multiple tables that do not exist: command-line"); 361 362 List<TableName> tables = Lists.newArrayList(table2, table3); 363 String backupId = fullTableBackup(tables); 364 assertTrue(checkSucceeded(backupId)); 365 366 TableName[] restore_tableset = 367 new TableName[] { TableName.valueOf("faketable1"), TableName.valueOf("faketable2") }; 368 TableName[] tablemap = new TableName[] { table2_restore, table3_restore }; 369 String[] args = new String[] { BACKUP_ROOT_DIR, backupId, 370 StringUtils.join(restore_tableset, ","), "-m", StringUtils.join(tablemap, ",") }; 371 // Run restore 372 int ret = ToolRunner.run(conf1, new RestoreDriver(), args); 373 assertTrue(ret != 0); 374 } 375}