[ 
https://issues.apache.org/jira/browse/HBASE-8626?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Vinod updated HBASE-8626:
-------------------------

    Attachment: TestRowMutations.java

Test case to reproduce the issue.
                
> RowMutations fail when Delete and Put on same columnFamily/column/row
> ---------------------------------------------------------------------
>
>                 Key: HBASE-8626
>                 URL: https://issues.apache.org/jira/browse/HBASE-8626
>             Project: HBase
>          Issue Type: Bug
>          Components: regionserver
>    Affects Versions: 0.94.7
>         Environment: Ubuntu 12.04, HBase 0.94.7
>            Reporter: Vinod
>             Fix For: 0.94.7
>
>         Attachments: TestRowMutations.java
>
>
> When RowMutations have a Delete followed by Put to same column family or 
> columns or rows, only the Delete is happening while the Put is ignored so 
> atomicity of RowMutations is broken for such cases.
> Attached is a unit test where the following tests are failing:
> - testDeleteCFThenPutInSameCF: Delete a column family and then Put to same 
> column family.
> - testDeleteColumnThenPutSameColumn: Delete a column and then Put to same 
> column.
> - testDeleteRowThenPutSameRow: Delete a row and then Put to same row
> ------------------
> package org.apache.hadoop.hbase.regionserver;
> import org.apache.hadoop.conf.Configuration;
> import org.apache.hadoop.fs.Path;
> import org.apache.hadoop.hbase.*;
> import org.apache.hadoop.hbase.client.*;
> import org.apache.hadoop.hbase.util.Bytes;
> import org.apache.hadoop.hbase.util.EnvironmentEdgeManagerTestHelper;
> import org.junit.experimental.categories.Category;
> import java.io.IOException;
> import java.util.NavigableMap;
> /**
>  * Tests for {@link RowMutations} where we combine various scenarios of 
> Delete followed by Put and vice versa.
>  */
> @Category(MediumTests.class)
> public class TestRowMutations extends HBaseTestCase {
>     HRegion region = null;
>     private HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
>     private final String DIR = 
> TEST_UTIL.getDataTestDir("TestAtomicOperation").toString();
>     static final byte[] tableName = Bytes.toBytes("TRM_testtable");
>     static final byte [] row = Bytes.toBytes("rowA");
>     static final byte[] cf1 = Bytes.toBytes("cf1");
>     static final byte[] cf2 = Bytes.toBytes("cf2");
>     static final byte[] qual1 = Bytes.toBytes("qual1");
>     static final byte[] qual2 = Bytes.toBytes("qual2");
>     static final byte[] value1 = Bytes.toBytes("value1");
>     static final byte[] value2 = Bytes.toBytes("value2");
>     /**
>      * Test {@link RowMutations} where we Delete a column family and then Put 
> to same column family. Fails currently.
>      * @throws IOException
>      */
>     public void testDeleteCFThenPutInSameCF() throws IOException {
>         initHRegion(tableName, getName(), HBaseConfiguration.create(), cf1);
>         //delete entire column family
>         Delete delete = new Delete(row);
>         delete.deleteFamily(cf1);
>         //Put to same column family
>         Put put = new Put(row);
>         put.add(cf1, qual1, value1);
>         put.add(cf1, qual2, value2);
>         RowMutations rm = new RowMutations(row);
>         rm.add(delete);
>         rm.add(put);
>         region.mutateRow(rm);
>         Result result = region.get(new Get(row));
>         NavigableMap<byte[],byte[]> familyMap = result.getFamilyMap(cf1);
>         assertNotNull(familyMap);
>         assertEquals(2, familyMap.size());
>         assertEquals(value1, familyMap.get(qual1));
>         assertEquals(value2, familyMap.get(qual2));
>     }
>     /**
>      * Test {@link RowMutations} where we Delete a column and then Put to 
> same column. Fails currently
>      * @throws IOException
>      */
>     public void testDeleteColumnThenPutSameColumn() throws IOException {
>         initHRegion(tableName, getName(), HBaseConfiguration.create(), cf1);
>         //delete columns
>         Delete delete = new Delete(row);
>         delete.deleteColumn(cf1, qual1);
>         delete.deleteColumn(cf1, qual2);
>         //Put to same columns
>         Put put = new Put(row);
>         put.add(cf1, qual1, value1);
>         put.add(cf1, qual2, value2);
>         RowMutations rm = new RowMutations(row);
>         rm.add(delete);
>         rm.add(put);
>         region.mutateRow(rm);
>         Result result = region.get(new Get(row));
>         NavigableMap<byte[],byte[]> familyMap = result.getFamilyMap(cf1);
>         assertNotNull(familyMap);
>         assertEquals(2, familyMap.size());
>         assertEquals(value1, familyMap.get(qual1));
>         assertEquals(value2, familyMap.get(qual2));
>     }
>     /**
>      * Test {@link RowMutations} where we Delete a row and then Put to same 
> row. Fails currently.
>      * @throws IOException
>      */
>     public void testDeleteRowThenPutSameRow() throws IOException {
>         initHRegion(tableName, getName(), HBaseConfiguration.create(), cf1);
>         //delete row
>         Delete delete = new Delete(row);
>         //Put to same row
>         Put put = new Put(row);
>         put.add(cf1, qual1, value1);
>         put.add(cf1, qual2, value2);
>         RowMutations rm = new RowMutations(row);
>         rm.add(delete);
>         rm.add(put);
>         region.mutateRow(rm);
>         Result result = region.get(new Get(row));
>         NavigableMap<byte[],byte[]> familyMap = result.getFamilyMap(cf1);
>         assertNotNull(familyMap);
>         assertEquals(2, familyMap.size());
>         assertEquals(value1, familyMap.get(qual1));
>         assertEquals(value2, familyMap.get(qual2));
>     }
>     /**
>      * Test {@link RowMutations} where we Put to a column family and then 
> Delete same column family.
>      * @throws IOException
>      */
>     public void testPutCFThenDeleteSameCF() throws IOException {
>         initHRegion(tableName, getName(), HBaseConfiguration.create(), cf1);
>         //Put to some column family
>         Put put = new Put(row);
>         put.add(cf1, qual1, value1);
>         put.add(cf1, qual2, value2);
>         //delete same column family
>         Delete delete = new Delete(row);
>         delete.deleteFamily(cf1);
>         RowMutations rm = new RowMutations(row);
>         rm.add(put);
>         rm.add(delete);
>         region.mutateRow(rm);
>         Result result = region.get(new Get(row));
>         NavigableMap<byte[],byte[]> familyMap = result.getFamilyMap(cf1);
>         assertNull(familyMap);
>     }
>     /**
>      * Test {@link RowMutations} where we Put to a column and then Delete 
> same column.
>      * @throws IOException
>      */
>     public void testPutToColumnThenDeleteSameColumn() throws IOException {
>         initHRegion(tableName, getName(), HBaseConfiguration.create(), cf1);
>         //Put to some columns
>         Put put = new Put(row);
>         put.add(cf1, qual1, value1);
>         put.add(cf1, qual2, value2);
>         //delete same columns
>         Delete delete = new Delete(row);
>         delete.deleteColumn(cf1, qual1);
>         delete.deleteColumn(cf1, qual2);
>         RowMutations rm = new RowMutations(row);
>         rm.add(put);
>         rm.add(delete);
>         region.mutateRow(rm);
>         Result result = region.get(new Get(row));
>         NavigableMap<byte[],byte[]> familyMap = result.getFamilyMap(cf1);
>         assertNull(familyMap);
>     }
>     /**
>      * Test {@link RowMutations} where we Put to a row and then Delete same 
> row.
>      * @throws IOException
>      */
>     public void testPutRowThenDeleteSameRow() throws IOException {
>         initHRegion(tableName, getName(), HBaseConfiguration.create(), cf1);
>         //delete row
>         Delete delete = new Delete(row);
>         //Put to same row
>         Put put = new Put(row);
>         put.add(cf1, qual1, value1);
>         put.add(cf1, qual2, value2);
>         RowMutations rm = new RowMutations(row);
>         rm.add(put);
>         rm.add(delete);
>         region.mutateRow(rm);
>         Result result = region.get(new Get(row));
>         NavigableMap<byte[],byte[]> familyMap = result.getFamilyMap(cf1);
>         assertNull(familyMap);
>     }
>     /**
>      * Test {@link RowMutations} where we Delete a column family and then Put 
> to different column family. Passes currently.
>      * @throws IOException
>      */
>     public void testDeleteCFThenPutInDiffCF() throws IOException {
>         initHRegion(tableName, getName(), HBaseConfiguration.create(), cf1, 
> cf2);
>         //delete some column family
>         Delete delete = new Delete(row);
>         delete.deleteFamily(cf1);
>         //Put to different column family
>         Put put = new Put(row);
>         put.add(cf2, qual1, value1);
>         put.add(cf2, qual2, value2);
>         RowMutations rm = new RowMutations(row);
>         rm.add(delete);
>         rm.add(put);
>         region.mutateRow(rm);
>         Result result = region.get(new Get(row));
>         NavigableMap<byte[],byte[]> familyMap = result.getFamilyMap(cf2);
>         assertNotNull(familyMap);
>         assertEquals(2, familyMap.size());
>         assertEquals(value1, familyMap.get(qual1));
>         assertEquals(value2, familyMap.get(qual2));
>         NavigableMap<byte[],byte[]> familyMap1 = result.getFamilyMap(cf1);
>         assertEquals(0, familyMap1.size());  //TODO: why is familyMap1 empty 
> instead of null?
>     }
>     /**
>      * Test {@link RowMutations} where we Delete a column and then Put to 
> different column. Passes currently.
>      * @throws IOException
>      */
>     public void testDeleteColumnThenPutDiffColumn() throws IOException {
>         initHRegion(tableName, getName(), HBaseConfiguration.create(), cf1, 
> cf2);
>         //delete columns
>         Delete delete = new Delete(row);
>         delete.deleteColumn(cf1, qual1);
>         //Put to different column, one in same column family and one in 
> another column family
>         Put put = new Put(row);
>         put.add(cf1, qual2, value2);
>         put.add(cf2, qual2, value2);
>         RowMutations rm = new RowMutations(row);
>         rm.add(delete);
>         rm.add(put);
>         region.mutateRow(rm);
>         Result result = region.get(new Get(row));
>         NavigableMap<byte[],byte[]> familyMap = result.getFamilyMap(cf1);
>         assertNotNull(familyMap);
>         assertEquals(1, familyMap.size());
>         assertEquals(value2, familyMap.get(qual2));
>         NavigableMap<byte[],byte[]> familyMap2 = result.getFamilyMap(cf2);
>         assertNotNull(familyMap2);
>         assertEquals(1, familyMap2.size());
>         assertEquals(value2, familyMap2.get(qual2));
>     }
>     private void initHRegion (byte [] tableName, String callingMethod,
>                               Configuration conf, byte [] ... families)
>             throws IOException{
>         HTableDescriptor htd = new HTableDescriptor(tableName);
>         for(byte [] family : families) {
>             htd.addFamily(new HColumnDescriptor(family));
>         }
>         HRegionInfo info = new HRegionInfo(htd.getName(), null, null, false);
>         Path path = new Path(DIR + callingMethod);
>         if (fs.exists(path)) {
>             if (!fs.delete(path, true)) {
>                 throw new IOException("Failed delete of " + path);
>             }
>         }
>         region = HRegion.createHRegion(info, path, conf, htd);
>     }
>     @Override
>     protected void setUp() throws Exception {
>         super.setUp();
>     }
>     @Override
>     protected void tearDown() throws Exception {
>         super.tearDown();
>         EnvironmentEdgeManagerTestHelper.reset();
>     }
> }
> ----------------

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to