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.master.region; 019 020import static org.junit.jupiter.api.Assertions.assertArrayEquals; 021import static org.junit.jupiter.api.Assertions.assertEquals; 022import static org.junit.jupiter.api.Assertions.assertFalse; 023import static org.junit.jupiter.api.Assertions.assertNull; 024import static org.junit.jupiter.api.Assertions.assertTrue; 025 026import java.io.IOException; 027import org.apache.hadoop.conf.Configuration; 028import org.apache.hadoop.fs.Path; 029import org.apache.hadoop.hbase.HBaseConfiguration; 030import org.apache.hadoop.hbase.HConstants; 031import org.apache.hadoop.hbase.client.Get; 032import org.apache.hadoop.hbase.client.Put; 033import org.apache.hadoop.hbase.client.TableDescriptor; 034import org.apache.hadoop.hbase.regionserver.HRegion.FlushResult; 035import org.apache.hadoop.hbase.regionserver.HRegionFileSystem; 036import org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTrackerFactory; 037import org.apache.hadoop.hbase.testclassification.MasterTests; 038import org.apache.hadoop.hbase.testclassification.MediumTests; 039import org.apache.hadoop.hbase.util.Bytes; 040import org.apache.hadoop.hbase.util.CommonFSUtils; 041import org.apache.hadoop.hbase.util.FSTableDescriptors; 042import org.junit.jupiter.api.Tag; 043import org.junit.jupiter.api.Test; 044 045@Tag(MasterTests.TAG) 046@Tag(MediumTests.TAG) 047public class TestMasterRegionInitialize extends MasterRegionTestBase { 048 049 @Test 050 public void testUpgrade() throws IOException { 051 Path rootDir = new Path(htu.getDataTestDir(), REGION_DIR_NAME); 052 Path tableDir = 053 CommonFSUtils.getTableDir(rootDir, region.region.getTableDescriptor().getTableName()); 054 Path initializingFlag = new Path(tableDir, MasterRegion.INITIALIZING_FLAG); 055 Path initializedFlag = new Path(tableDir, MasterRegion.INITIALIZED_FLAG); 056 HRegionFileSystem hfs = region.region.getRegionFileSystem(); 057 assertFalse(hfs.getFileSystem().exists(initializingFlag)); 058 assertTrue(hfs.getFileSystem().exists(initializedFlag)); 059 byte[] row = Bytes.toBytes("row"); 060 byte[] cf = CF1; 061 byte[] cq = Bytes.toBytes("qual"); 062 byte[] value = Bytes.toBytes("value"); 063 region.update(r -> r.put(new Put(row).addColumn(cf, cq, value))); 064 assertEquals(FlushResult.Result.FLUSHED_NO_COMPACTION_NEEDED, region.flush(true).getResult()); 065 // delete initialized flag to simulate old implementation 066 hfs.getFileSystem().delete(initializedFlag, true); 067 FSTableDescriptors.deleteTableDescriptors(hfs.getFileSystem(), tableDir); 068 assertNull(FSTableDescriptors.getTableDescriptorFromFs(hfs.getFileSystem(), tableDir)); 069 // reopen, with new file tracker 070 region.close(false); 071 htu.getConfiguration().set(StoreFileTrackerFactory.TRACKER_IMPL, 072 StoreFileTrackerFactory.Trackers.FILE.name()); 073 createMasterRegion(); 074 075 // make sure we successfully upgrade to new implementation without data loss 076 hfs = region.region.getRegionFileSystem(); 077 assertFalse(hfs.getFileSystem().exists(initializingFlag)); 078 assertTrue(hfs.getFileSystem().exists(initializedFlag)); 079 TableDescriptor td = FSTableDescriptors.getTableDescriptorFromFs(hfs.getFileSystem(), tableDir); 080 assertEquals(StoreFileTrackerFactory.Trackers.FILE.name(), 081 td.getValue(StoreFileTrackerFactory.TRACKER_IMPL)); 082 assertArrayEquals(value, region.get(new Get(row)).getValue(cf, cq)); 083 } 084 085 @Test 086 public void testInitializingCleanup() throws IOException { 087 Path rootDir = new Path(htu.getDataTestDir(), REGION_DIR_NAME); 088 Path tableDir = 089 CommonFSUtils.getTableDir(rootDir, region.region.getTableDescriptor().getTableName()); 090 Path initializingFlag = new Path(tableDir, MasterRegion.INITIALIZING_FLAG); 091 Path initializedFlag = new Path(tableDir, MasterRegion.INITIALIZED_FLAG); 092 HRegionFileSystem hfs = region.region.getRegionFileSystem(); 093 assertFalse(hfs.getFileSystem().exists(initializingFlag)); 094 assertTrue(hfs.getFileSystem().exists(initializedFlag)); 095 byte[] row = Bytes.toBytes("row"); 096 byte[] cf = CF1; 097 byte[] cq = Bytes.toBytes("qual"); 098 byte[] value = Bytes.toBytes("value"); 099 region.update(r -> r.put(new Put(row).addColumn(cf, cq, value))); 100 // delete initialized flag and touch a initializing flag, to simulate initializing in progress 101 hfs.getFileSystem().delete(initializedFlag, true); 102 if (!hfs.getFileSystem().mkdirs(initializingFlag)) { 103 throw new IOException("can not touch " + initializedFlag); 104 } 105 106 region.close(false); 107 createMasterRegion(); 108 hfs = region.region.getRegionFileSystem(); 109 assertFalse(hfs.getFileSystem().exists(initializingFlag)); 110 assertTrue(hfs.getFileSystem().exists(initializedFlag)); 111 112 // but the data should have been cleaned up 113 assertTrue(region.get(new Get(row)).isEmpty()); 114 } 115 116 @Test 117 public void testMasterRegionDirSuffix() { 118 String currentMasterRegionDirName = MasterRegionFactory.getMasterRegionDirName(); 119 assertEquals("MasterData", currentMasterRegionDirName, 120 "Default master region directory should be MasterData"); 121 122 Configuration confWithSuffix = HBaseConfiguration.create(); 123 String suffix = "replica1"; 124 confWithSuffix.set(HConstants.HBASE_META_TABLE_SUFFIX, suffix); 125 String dirNameWithSuffix = MasterRegionFactory.initMasterRegionDirName(confWithSuffix); 126 String expectedDirName = "MasterData_" + suffix; 127 assertEquals(expectedDirName, dirNameWithSuffix, 128 "Directory name should have suffix when configured"); 129 } 130}