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