Search in sources :

Example 6 with FSHLog

use of org.apache.hadoop.hbase.regionserver.wal.FSHLog in project hbase by apache.

the class TestHRegion method testDataInMemoryWithoutWAL.

@Test
public void testDataInMemoryWithoutWAL() throws IOException {
    FileSystem fs = FileSystem.get(CONF);
    Path rootDir = new Path(dir + "testDataInMemoryWithoutWAL");
    FSHLog hLog = new FSHLog(fs, rootDir, "testDataInMemoryWithoutWAL", CONF);
    HRegion region = initHRegion(tableName, null, null, false, Durability.SYNC_WAL, hLog, COLUMN_FAMILY_BYTES);
    Cell originalCell = CellUtil.createCell(row, COLUMN_FAMILY_BYTES, qual1, System.currentTimeMillis(), KeyValue.Type.Put.getCode(), value1);
    final long originalSize = KeyValueUtil.length(originalCell);
    Cell addCell = CellUtil.createCell(row, COLUMN_FAMILY_BYTES, qual1, System.currentTimeMillis(), KeyValue.Type.Put.getCode(), Bytes.toBytes("xxxxxxxxxx"));
    final long addSize = KeyValueUtil.length(addCell);
    LOG.info("originalSize:" + originalSize + ", addSize:" + addSize);
    // start test. We expect that the addPut's durability will be replaced
    // by originalPut's durability.
    // case 1:
    testDataInMemoryWithoutWAL(region, new Put(row).add(originalCell).setDurability(Durability.SKIP_WAL), new Put(row).add(addCell).setDurability(Durability.SKIP_WAL), originalSize + addSize);
    // case 2:
    testDataInMemoryWithoutWAL(region, new Put(row).add(originalCell).setDurability(Durability.SKIP_WAL), new Put(row).add(addCell).setDurability(Durability.SYNC_WAL), originalSize + addSize);
    // case 3:
    testDataInMemoryWithoutWAL(region, new Put(row).add(originalCell).setDurability(Durability.SYNC_WAL), new Put(row).add(addCell).setDurability(Durability.SKIP_WAL), 0);
    // case 4:
    testDataInMemoryWithoutWAL(region, new Put(row).add(originalCell).setDurability(Durability.SYNC_WAL), new Put(row).add(addCell).setDurability(Durability.SYNC_WAL), 0);
}
Also used : Path(org.apache.hadoop.fs.Path) FileSystem(org.apache.hadoop.fs.FileSystem) FaultyFileSystem(org.apache.hadoop.hbase.regionserver.TestStore.FaultyFileSystem) Cell(org.apache.hadoop.hbase.Cell) Put(org.apache.hadoop.hbase.client.Put) FSHLog(org.apache.hadoop.hbase.regionserver.wal.FSHLog) Test(org.junit.Test)

Example 7 with FSHLog

use of org.apache.hadoop.hbase.regionserver.wal.FSHLog in project hbase by apache.

the class TestHRegion method testFlushMarkersWALFail.

@Test
public void testFlushMarkersWALFail() throws Exception {
    // test the cases where the WAL append for flush markers fail.
    byte[] family = Bytes.toBytes("family");
    // spy an actual WAL implementation to throw exception (was not able to mock)
    Path logDir = TEST_UTIL.getDataTestDirOnTestFS(method + "log");
    final Configuration walConf = new Configuration(TEST_UTIL.getConfiguration());
    FSUtils.setRootDir(walConf, logDir);
    // Make up a WAL that we can manipulate at append time.
    class FailAppendFlushMarkerWAL extends FSHLog {

        volatile FlushAction[] flushActions = null;

        public FailAppendFlushMarkerWAL(FileSystem fs, Path root, String logDir, Configuration conf) throws IOException {
            super(fs, root, logDir, conf);
        }

        @Override
        protected Writer createWriterInstance(Path path) throws IOException {
            final Writer w = super.createWriterInstance(path);
            return new Writer() {

                @Override
                public void close() throws IOException {
                    w.close();
                }

                @Override
                public void sync() throws IOException {
                    w.sync();
                }

                @Override
                public void append(Entry entry) throws IOException {
                    List<Cell> cells = entry.getEdit().getCells();
                    if (WALEdit.isMetaEditFamily(cells.get(0))) {
                        FlushDescriptor desc = WALEdit.getFlushDescriptor(cells.get(0));
                        if (desc != null) {
                            for (FlushAction flushAction : flushActions) {
                                if (desc.getAction().equals(flushAction)) {
                                    throw new IOException("Failed to append flush marker! " + flushAction);
                                }
                            }
                        }
                    }
                    w.append(entry);
                }

                @Override
                public long getLength() {
                    return w.getLength();
                }
            };
        }
    }
    FailAppendFlushMarkerWAL wal = new FailAppendFlushMarkerWAL(FileSystem.get(walConf), FSUtils.getRootDir(walConf), method, walConf);
    this.region = initHRegion(tableName, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, false, Durability.USE_DEFAULT, wal, family);
    try {
        int i = 0;
        Put put = new Put(Bytes.toBytes(i));
        // have to skip mocked wal
        put.setDurability(Durability.SKIP_WAL);
        put.addColumn(family, Bytes.toBytes(i), Bytes.toBytes(i));
        region.put(put);
        // 1. Test case where START_FLUSH throws exception
        wal.flushActions = new FlushAction[] { FlushAction.START_FLUSH };
        // start cache flush will throw exception
        try {
            region.flush(true);
            fail("This should have thrown exception");
        } catch (DroppedSnapshotException unexpected) {
            // this should not be a dropped snapshot exception. Meaning that RS will not abort
            throw unexpected;
        } catch (IOException expected) {
        // expected
        }
        // The WAL is hosed now. It has two edits appended. We cannot roll the log without it
        // throwing a DroppedSnapshotException to force an abort. Just clean up the mess.
        region.close(true);
        wal.close();
        // 2. Test case where START_FLUSH succeeds but COMMIT_FLUSH will throw exception
        wal.flushActions = new FlushAction[] { FlushAction.COMMIT_FLUSH };
        wal = new FailAppendFlushMarkerWAL(FileSystem.get(walConf), FSUtils.getRootDir(walConf), method, walConf);
        this.region = initHRegion(tableName, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, false, Durability.USE_DEFAULT, wal, family);
        region.put(put);
        // 3. Test case where ABORT_FLUSH will throw exception.
        // Even if ABORT_FLUSH throws exception, we should not fail with IOE, but continue with
        // DroppedSnapshotException. Below COMMMIT_FLUSH will cause flush to abort
        wal.flushActions = new FlushAction[] { FlushAction.COMMIT_FLUSH, FlushAction.ABORT_FLUSH };
        try {
            region.flush(true);
            fail("This should have thrown exception");
        } catch (DroppedSnapshotException expected) {
        // we expect this exception, since we were able to write the snapshot, but failed to
        // write the flush marker to WAL
        } catch (IOException unexpected) {
            throw unexpected;
        }
    } finally {
        HBaseTestingUtility.closeRegionAndWAL(this.region);
        this.region = null;
    }
}
Also used : Path(org.apache.hadoop.fs.Path) Configuration(org.apache.hadoop.conf.Configuration) HBaseConfiguration(org.apache.hadoop.hbase.HBaseConfiguration) DroppedSnapshotException(org.apache.hadoop.hbase.DroppedSnapshotException) ByteString(org.apache.hadoop.hbase.shaded.com.google.protobuf.ByteString) InterruptedIOException(java.io.InterruptedIOException) IOException(java.io.IOException) FlushDescriptor(org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.FlushDescriptor) StoreFlushDescriptor(org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.FlushDescriptor.StoreFlushDescriptor) Put(org.apache.hadoop.hbase.client.Put) FSHLog(org.apache.hadoop.hbase.regionserver.wal.FSHLog) FlushAction(org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.FlushDescriptor.FlushAction) FileSystem(org.apache.hadoop.fs.FileSystem) FaultyFileSystem(org.apache.hadoop.hbase.regionserver.TestStore.FaultyFileSystem) Cell(org.apache.hadoop.hbase.Cell) Writer(org.apache.hadoop.hbase.wal.WALProvider.Writer) Test(org.junit.Test)

Example 8 with FSHLog

use of org.apache.hadoop.hbase.regionserver.wal.FSHLog in project hbase by apache.

the class TestWALLockup method testLockup16960.

/**
   * Reproduce locking up that happens when there's no further syncs after
   * append fails, and causing an isolated sync then infinite wait. See
   * HBASE-16960. If below is broken, we will see this test timeout because it
   * is locked up.
   * <p/>
   * Steps for reproduce:<br/>
   * 1. Trigger server abort through dodgyWAL1<br/>
   * 2. Add a {@link DummyWALActionsListener} to dodgyWAL2 to cause ringbuffer
   * event handler thread sleep for a while thus keeping {@code endOfBatch}
   * false<br/>
   * 3. Publish a sync then an append which will throw exception, check whether
   * the sync could return
   */
@Test(timeout = 20000)
public void testLockup16960() throws IOException {
    // A WAL that we can have throw exceptions when a flag is set.
    class DodgyFSLog extends FSHLog {

        // Set this when want the WAL to start throwing exceptions.
        volatile boolean throwException = false;

        public DodgyFSLog(FileSystem fs, Path root, String logDir, Configuration conf) throws IOException {
            super(fs, root, logDir, conf);
        }

        @Override
        protected Writer createWriterInstance(Path path) throws IOException {
            final Writer w = super.createWriterInstance(path);
            return new Writer() {

                @Override
                public void close() throws IOException {
                    w.close();
                }

                @Override
                public void sync() throws IOException {
                    if (throwException) {
                        throw new IOException("FAKE! Failed to replace a bad datanode...SYNC");
                    }
                    w.sync();
                }

                @Override
                public void append(Entry entry) throws IOException {
                    if (throwException) {
                        throw new IOException("FAKE! Failed to replace a bad datanode...APPEND");
                    }
                    w.append(entry);
                }

                @Override
                public long getLength() {
                    return w.getLength();
                }
            };
        }

        @Override
        protected long doReplaceWriter(Path oldPath, Path newPath, Writer nextWriter) throws IOException {
            if (throwException) {
                throw new FailedLogCloseException("oldPath=" + oldPath + ", newPath=" + newPath);
            }
            long oldFileLen = 0L;
            oldFileLen = super.doReplaceWriter(oldPath, newPath, nextWriter);
            return oldFileLen;
        }
    }
    // Mocked up server and regionserver services. Needed below.
    Server server = new DummyServer(CONF, ServerName.valueOf("hostname1.example.org", 1234, 1L).toString());
    RegionServerServices services = Mockito.mock(RegionServerServices.class);
    CONF.setLong("hbase.regionserver.hlog.sync.timeout", 10000);
    // OK. Now I have my mocked up Server & RegionServerServices and dodgy WAL,
    // go ahead with test.
    FileSystem fs = FileSystem.get(CONF);
    Path rootDir = new Path(dir + getName());
    DodgyFSLog dodgyWAL1 = new DodgyFSLog(fs, rootDir, getName(), CONF);
    Path rootDir2 = new Path(dir + getName() + "2");
    final DodgyFSLog dodgyWAL2 = new DodgyFSLog(fs, rootDir2, getName() + "2", CONF);
    // Add a listener to force ringbuffer event handler sleep for a while
    dodgyWAL2.registerWALActionsListener(new DummyWALActionsListener());
    // I need a log roller running.
    LogRoller logRoller = new LogRoller(server, services);
    logRoller.addWAL(dodgyWAL1);
    logRoller.addWAL(dodgyWAL2);
    // There is no 'stop' once a logRoller is running.. it just dies.
    logRoller.start();
    // Now get a region and start adding in edits.
    HTableDescriptor htd = new HTableDescriptor(TableName.META_TABLE_NAME);
    final HRegion region = initHRegion(tableName, null, null, dodgyWAL1);
    byte[] bytes = Bytes.toBytes(getName());
    NavigableMap<byte[], Integer> scopes = new TreeMap<>(Bytes.BYTES_COMPARATOR);
    scopes.put(COLUMN_FAMILY_BYTES, 0);
    MultiVersionConcurrencyControl mvcc = new MultiVersionConcurrencyControl();
    try {
        Put put = new Put(bytes);
        put.addColumn(COLUMN_FAMILY_BYTES, Bytes.toBytes("1"), bytes);
        WALKey key = new WALKey(region.getRegionInfo().getEncodedNameAsBytes(), htd.getTableName(), System.currentTimeMillis(), mvcc, scopes);
        WALEdit edit = new WALEdit();
        CellScanner CellScanner = put.cellScanner();
        assertTrue(CellScanner.advance());
        edit.add(CellScanner.current());
        LOG.info("SET throwing of exception on append");
        dodgyWAL1.throwException = true;
        // This append provokes a WAL roll request
        dodgyWAL1.append(region.getRegionInfo(), key, edit, true);
        boolean exception = false;
        try {
            dodgyWAL1.sync();
        } catch (Exception e) {
            exception = true;
        }
        assertTrue("Did not get sync exception", exception);
        // cause server abort.
        try {
            // wait LogRoller exit.
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        final CountDownLatch latch = new CountDownLatch(1);
        // make RingBufferEventHandler sleep 1s, so the following sync
        // endOfBatch=false
        key = new WALKey(region.getRegionInfo().getEncodedNameAsBytes(), TableName.valueOf("sleep"), System.currentTimeMillis(), mvcc, scopes);
        dodgyWAL2.append(region.getRegionInfo(), key, edit, true);
        Thread t = new Thread("Sync") {

            public void run() {
                try {
                    dodgyWAL2.sync();
                } catch (IOException e) {
                    LOG.info("In sync", e);
                }
                latch.countDown();
                LOG.info("Sync exiting");
            }

            ;
        };
        t.setDaemon(true);
        t.start();
        try {
            // make sure sync have published.
            Thread.sleep(100);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        // make append throw DamagedWALException
        key = new WALKey(region.getRegionInfo().getEncodedNameAsBytes(), TableName.valueOf("DamagedWALException"), System.currentTimeMillis(), mvcc, scopes);
        dodgyWAL2.append(region.getRegionInfo(), key, edit, true);
        while (latch.getCount() > 0) {
            Threads.sleep(100);
        }
        assertTrue(server.isAborted());
    } finally {
        if (logRoller != null) {
            logRoller.close();
        }
        try {
            if (region != null) {
                region.close();
            }
            if (dodgyWAL1 != null) {
                dodgyWAL1.close();
            }
            if (dodgyWAL2 != null) {
                dodgyWAL2.close();
            }
        } catch (Exception e) {
            LOG.info("On way out", e);
        }
    }
}
Also used : Configuration(org.apache.hadoop.conf.Configuration) Server(org.apache.hadoop.hbase.Server) FailedLogCloseException(org.apache.hadoop.hbase.regionserver.wal.FailedLogCloseException) CellScanner(org.apache.hadoop.hbase.CellScanner) FSHLog(org.apache.hadoop.hbase.regionserver.wal.FSHLog) WALKey(org.apache.hadoop.hbase.wal.WALKey) WALEdit(org.apache.hadoop.hbase.regionserver.wal.WALEdit) FileSystem(org.apache.hadoop.fs.FileSystem) Path(org.apache.hadoop.fs.Path) IOException(java.io.IOException) TreeMap(java.util.TreeMap) CountDownLatch(java.util.concurrent.CountDownLatch) Put(org.apache.hadoop.hbase.client.Put) DamagedWALException(org.apache.hadoop.hbase.regionserver.wal.DamagedWALException) IOException(java.io.IOException) FailedLogCloseException(org.apache.hadoop.hbase.regionserver.wal.FailedLogCloseException) HTableDescriptor(org.apache.hadoop.hbase.HTableDescriptor) Writer(org.apache.hadoop.hbase.wal.WALProvider.Writer) Test(org.junit.Test)

Example 9 with FSHLog

use of org.apache.hadoop.hbase.regionserver.wal.FSHLog in project hbase by apache.

the class TestWALMonotonicallyIncreasingSeqId method TestWALMonotonicallyIncreasingSeqId.

@Test
public void TestWALMonotonicallyIncreasingSeqId() throws Exception {
    byte[][] families = new byte[][] { Bytes.toBytes("cf") };
    byte[] qf = Bytes.toBytes("cq");
    HTableDescriptor htd = getTableDesc(TableName.valueOf(name.getMethodName()), families);
    HRegion region = (HRegion) initHRegion(htd, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, 0);
    List<Thread> putThreads = new ArrayList<>();
    for (int i = 0; i < 1; i++) {
        putThreads.add(new PutThread(region));
    }
    IncThread incThread = new IncThread(region);
    for (int i = 0; i < 1; i++) {
        putThreads.get(i).start();
    }
    incThread.start();
    incThread.join();
    Path logPath = ((FSHLog) region.getWAL()).getCurrentFileName();
    region.getWAL().rollWriter();
    Thread.sleep(10);
    Path hbaseDir = new Path(walConf.get(HConstants.HBASE_DIR));
    Path oldWalsDir = new Path(hbaseDir, HConstants.HREGION_OLDLOGDIR_NAME);
    WAL.Reader reader = null;
    try {
        reader = wals.createReader(fileSystem, logPath);
    } catch (Throwable t) {
        reader = wals.createReader(fileSystem, new Path(oldWalsDir, logPath.getName()));
    }
    WAL.Entry e;
    try {
        long currentMaxSeqid = 0;
        while ((e = reader.next()) != null) {
            if (!WALEdit.isMetaEditFamily(e.getEdit().getCells().get(0))) {
                long currentSeqid = e.getKey().getSequenceId();
                if (currentSeqid > currentMaxSeqid) {
                    currentMaxSeqid = currentSeqid;
                } else {
                    Assert.fail("Current max Seqid is " + currentMaxSeqid + ", but the next seqid in wal is smaller:" + currentSeqid);
                }
            }
        }
    } finally {
        if (reader != null) {
            reader.close();
        }
        if (region != null) {
            region.close();
        }
    }
}
Also used : Path(org.apache.hadoop.fs.Path) WAL(org.apache.hadoop.hbase.wal.WAL) ArrayList(java.util.ArrayList) FSHLog(org.apache.hadoop.hbase.regionserver.wal.FSHLog) Test(org.junit.Test)

Aggregations

Path (org.apache.hadoop.fs.Path)9 FSHLog (org.apache.hadoop.hbase.regionserver.wal.FSHLog)9 FileSystem (org.apache.hadoop.fs.FileSystem)8 Test (org.junit.Test)8 Put (org.apache.hadoop.hbase.client.Put)7 IOException (java.io.IOException)5 Configuration (org.apache.hadoop.conf.Configuration)4 FaultyFileSystem (org.apache.hadoop.hbase.regionserver.TestStore.FaultyFileSystem)4 Writer (org.apache.hadoop.hbase.wal.WALProvider.Writer)4 HTableDescriptor (org.apache.hadoop.hbase.HTableDescriptor)3 Server (org.apache.hadoop.hbase.Server)3 InterruptedIOException (java.io.InterruptedIOException)2 TreeMap (java.util.TreeMap)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 Cell (org.apache.hadoop.hbase.Cell)2 CellScanner (org.apache.hadoop.hbase.CellScanner)2 DroppedSnapshotException (org.apache.hadoop.hbase.DroppedSnapshotException)2 DamagedWALException (org.apache.hadoop.hbase.regionserver.wal.DamagedWALException)2 FailedLogCloseException (org.apache.hadoop.hbase.regionserver.wal.FailedLogCloseException)2 WALEdit (org.apache.hadoop.hbase.regionserver.wal.WALEdit)2