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.regionserver; 019 020import static org.apache.hadoop.hbase.HBaseTestingUtil.fam1; 021import static org.junit.jupiter.api.Assertions.assertEquals; 022import static org.junit.jupiter.api.Assertions.assertTrue; 023 024import java.io.IOException; 025import org.apache.hadoop.hbase.HBaseTestingUtil; 026import org.apache.hadoop.hbase.SingleProcessHBaseCluster; 027import org.apache.hadoop.hbase.TableName; 028import org.apache.hadoop.hbase.client.Admin; 029import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 030import org.apache.hadoop.hbase.client.Connection; 031import org.apache.hadoop.hbase.client.ConnectionFactory; 032import org.apache.hadoop.hbase.client.Durability; 033import org.apache.hadoop.hbase.client.Get; 034import org.apache.hadoop.hbase.client.Put; 035import org.apache.hadoop.hbase.client.Result; 036import org.apache.hadoop.hbase.client.RowMutations; 037import org.apache.hadoop.hbase.client.Table; 038import org.apache.hadoop.hbase.client.TableDescriptor; 039import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 040import org.apache.hadoop.hbase.testclassification.MediumTests; 041import org.apache.hadoop.hbase.testclassification.RegionServerTests; 042import org.apache.hadoop.hbase.util.Bytes; 043import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 044import org.junit.jupiter.api.AfterAll; 045import org.junit.jupiter.api.AfterEach; 046import org.junit.jupiter.api.BeforeAll; 047import org.junit.jupiter.api.BeforeEach; 048import org.junit.jupiter.api.Tag; 049import org.junit.jupiter.api.Test; 050 051@Tag(RegionServerTests.TAG) 052@Tag(MediumTests.TAG) 053public class TestMutateRowsRecovery { 054 055 private SingleProcessHBaseCluster cluster = null; 056 private Connection connection = null; 057 private static final int NB_SERVERS = 3; 058 059 static final byte[] qual1 = Bytes.toBytes("qual1"); 060 static final byte[] qual2 = Bytes.toBytes("qual2"); 061 static final byte[] value1 = Bytes.toBytes("value1"); 062 static final byte[] value2 = Bytes.toBytes("value2"); 063 static final byte[] row1 = Bytes.toBytes("rowA"); 064 static final byte[] row2 = Bytes.toBytes("rowB"); 065 066 static final HBaseTestingUtil TESTING_UTIL = new HBaseTestingUtil(); 067 068 @BeforeAll 069 public static void before() throws Exception { 070 TESTING_UTIL.startMiniCluster(NB_SERVERS); 071 } 072 073 @AfterAll 074 public static void after() throws Exception { 075 TESTING_UTIL.shutdownMiniCluster(); 076 } 077 078 @BeforeEach 079 public void setup() throws IOException { 080 TESTING_UTIL.ensureSomeNonStoppedRegionServersAvailable(NB_SERVERS); 081 this.connection = ConnectionFactory.createConnection(TESTING_UTIL.getConfiguration()); 082 this.cluster = TESTING_UTIL.getMiniHBaseCluster(); 083 } 084 085 @AfterEach 086 public void tearDown() throws IOException { 087 if (this.connection != null) { 088 this.connection.close(); 089 } 090 } 091 092 @Test 093 public void MutateRowsAndCheckPostKill() throws IOException, InterruptedException { 094 final TableName tableName = TableName.valueOf("test"); 095 Admin admin = null; 096 Table hTable = null; 097 try { 098 admin = connection.getAdmin(); 099 hTable = connection.getTable(tableName); 100 TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName) 101 .setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam1)).build(); 102 admin.createTable(tableDescriptor); 103 104 // Add a multi 105 RowMutations rm = new RowMutations(row1); 106 Put p1 = new Put(row1); 107 p1.addColumn(fam1, qual1, value1); 108 p1.setDurability(Durability.SYNC_WAL); 109 rm.add(p1); 110 hTable.mutateRow(rm); 111 112 // Add a put 113 Put p2 = new Put(row1); 114 p2.addColumn(fam1, qual2, value2); 115 p2.setDurability(Durability.SYNC_WAL); 116 hTable.put(p2); 117 118 HRegionServer rs1 = TESTING_UTIL.getRSForFirstRegionInTable(tableName); 119 long now = EnvironmentEdgeManager.currentTime(); 120 // Send the RS Load to ensure correct lastflushedseqid for stores 121 rs1.tryRegionServerReport(now - 30000, now); 122 // Kill the RS to trigger wal replay 123 cluster.killRegionServer(rs1.getServerName()); 124 125 // Ensure correct data exists 126 Get g1 = new Get(row1); 127 Result result = hTable.get(g1); 128 assertTrue(result.getValue(fam1, qual1) != null); 129 assertEquals(0, Bytes.compareTo(result.getValue(fam1, qual1), value1)); 130 assertTrue(result.getValue(fam1, qual2) != null); 131 assertEquals(0, Bytes.compareTo(result.getValue(fam1, qual2), value2)); 132 } finally { 133 if (admin != null) { 134 admin.close(); 135 } 136 if (hTable != null) { 137 hTable.close(); 138 } 139 } 140 } 141}