You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@hbase.apache.org by "Vinod (JIRA)" <ji...@apache.org> on 2013/05/26 16:58:20 UTC

[jira] [Created] (HBASE-8626) RowMutations fail when Delete and Put on same columnFamily/column/row

Vinod created HBASE-8626:
----------------------------

             Summary: 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


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