Tanuj Khurana created PHOENIX-7574:
--------------------------------------

             Summary: Phoenix Compaction doesn't correctly handle 
DeleteFamilyVersion markers
                 Key: PHOENIX-7574
                 URL: https://issues.apache.org/jira/browse/PHOENIX-7574
             Project: Phoenix
          Issue Type: Bug
    Affects Versions: 5.2.1, 5.2.0
            Reporter: Tanuj Khurana
         Attachments: delete_family_version_data_loss.txt

In Phoenix, the Read repair process on global indexes can insert 
DeleteFamilyVersion markers when there is a unverified index row update but no 
corresponding data table update. I found that phoenix compaction purges that 
row leading to a data loss. I created a test case in TableTTLIT to reproduce 
the problem. [^delete_family_version_data_loss.txt]
{code:java}
@Test
public void testDeleteFamilyVersion() throws Exception {
    // for the purpose of this test only considering cases when maxlookback is 0
    if (tableLevelMaxLooback == null || tableLevelMaxLooback != 0) {
        return;
    }
    if (multiCF == true) {
        return;
    }
    try (Connection conn = DriverManager.getConnection(getUrl())) {
        String tableName = "T_" + generateUniqueName();
        createTable(tableName);
        String indexName = "I_" + generateUniqueName();
        String indexDDL = String.format("create index %s on %s (val1) include 
(val2, val3)",
                indexName, tableName);
        conn.createStatement().execute(indexDDL);
        updateRow(conn, tableName, "a1");
        // make the index row unverified and fail the data table update
        IndexRegionObserver.setFailDataTableUpdatesForTesting(true);
        try {
            updateColumn(conn, tableName, "a1", 2, "col2_xyz");
            conn.commit();
            fail("An exception should have been thrown");
        } catch (Exception ignored) {
            // Ignore the exception
        } finally {
            IndexRegionObserver.setFailDataTableUpdatesForTesting(false);
        }
        TestUtil.dumpTable(conn, TableName.valueOf(indexName));
        // do a read on the index which should trigger a read repair
        String dql = "select count(*) from " + tableName;
        try (ResultSet rs = conn.createStatement().executeQuery(dql)) {
            PhoenixResultSet prs = rs.unwrap(PhoenixResultSet.class);
            String explainPlan = 
QueryUtil.getExplainPlan(prs.getUnderlyingIterator());
            assertTrue(explainPlan.contains(indexName));
            while (rs.next()) {
                assertEquals(1, rs.getInt(1));
            }
        }
        TestUtil.dumpTable(conn, TableName.valueOf(indexName));
        flush(TableName.valueOf(indexName));
        majorCompact(TableName.valueOf(indexName));
        TestUtil.dumpTable(conn, TableName.valueOf(indexName));
        // run the same query again after compaction
        try (ResultSet rs = conn.createStatement().executeQuery(dql)) {
            PhoenixResultSet prs = rs.unwrap(PhoenixResultSet.class);
            String explainPlan = 
QueryUtil.getExplainPlan(prs.getUnderlyingIterator());
            assertTrue(explainPlan.contains(indexName));
            while (rs.next()) {
                assertEquals(1, rs.getInt(1));
            }
        }
    }
} {code}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to