/** * truncate the current transaction logs * @param zxid the zxid to truncate the logs to * @return true if successful false if not */ public boolean truncate(long zxid) throws IOException { FileTxnIterator itr = null; try { itr = new FileTxnIterator(this.logDir, zxid); PositionInputStream input = itr.inputStream; if(input == null) { throw new IOException("No log files found to truncate! This could " + "happen if you still have snapshots from an old setup or " + "log files were deleted accidentally or dataLogDir was changed in zoo.cfg."); } long pos = input.getPosition(); // now, truncate at the current position RandomAccessFile raf = new RandomAccessFile(itr.logFile, "rw"); raf.setLength(pos); raf.close(); while (itr.goToNextLog()) { if (!itr.logFile.delete()) { LOG.warn("Unable to truncate {}", itr.logFile); } } } finally { close(itr); } return true; }
/** * initialize to the zxid specified * this is inclusive of the zxid * @throws IOException */ void init() throws IOException { storedFiles = new ArrayList<File>(); List<File> files = Util.sortDataDir(FileTxnLog.getLogFiles(logDir.listFiles(), 0), LOG_FILE_PREFIX, false); for (File f: files) { if (Util.getZxidFromName(f.getName(), LOG_FILE_PREFIX) >= zxid) { storedFiles.add(f); } // add the last logfile that is less than the zxid else if (Util.getZxidFromName(f.getName(), LOG_FILE_PREFIX) < zxid) { storedFiles.add(f); break; } } goToNextLog(); if (!next()) return; while (hdr.getZxid() < zxid) { if (!next()) return; } }
/** * the dbid of this transaction database * @return the dbid of this database */ public long getDbId() throws IOException { FileTxnIterator itr = new FileTxnIterator(logDir, 0); FileHeader fh=readHeader(itr.logFile); itr.close(); if(fh==null) throw new IOException("Unsupported Format."); return fh.getDbid(); }
Checksum crc = makeChecksumAlgorithm(); crc.update(bytes, 0, bytes.length); if (crcValue != crc.getValue()) if (!goToNextLog()) { return false;
/** * initialize to the zxid specified * this is inclusive of the zxid * @throws IOException */ void init() throws IOException { storedFiles = new ArrayList<File>(); List<File> files = Util.sortDataDir(FileTxnLog.getLogFiles(logDir.listFiles(), 0), "log", false); for (File f: files) { if (Util.getZxidFromName(f.getName(), "log") >= zxid) { storedFiles.add(f); } // add the last logfile that is less than the zxid else if (Util.getZxidFromName(f.getName(), "log") < zxid) { storedFiles.add(f); break; } } goToNextLog(); if (!next()) return; while (hdr.getZxid() < zxid) { if (!next()) return; } }
/** * truncate the current transaction logs * @param zxid the zxid to truncate the logs to * @return true if successful false if not */ public boolean truncate(long zxid) throws IOException { FileTxnIterator itr = new FileTxnIterator(this.logDir, zxid); PositionInputStream input = itr.inputStream; long pos = input.getPosition(); // now, truncate at the current position RandomAccessFile raf=new RandomAccessFile(itr.logFile,"rw"); raf.setLength(pos); raf.close(); while(itr.goToNextLog()) { if (!itr.logFile.delete()) { LOG.warn("Unable to truncate " + itr.logFile); } } return true; }
/** * Invoked to indicate that the input stream has been created. * @param ia input archive * @param is file input stream associated with the input archive. * @throws IOException **/ protected InputArchive createInputArchive(File logFile) throws IOException { if(inputStream==null){ inputStream= new PositionInputStream(new BufferedInputStream(new FileInputStream(logFile))); LOG.debug("Created new input stream " + logFile); ia = BinaryInputArchive.getArchive(inputStream); inStreamCreated(ia,inputStream); LOG.debug("Created new input archive " + logFile); } return ia; }
/** * go to the next logfile * @return true if there is one and false if there is no * new file to be read * @throws IOException */ private boolean goToNextLog() throws IOException { if (storedFiles.size() > 0) { this.logFile = storedFiles.remove(storedFiles.size()-1); ia = createInputArchive(this.logFile); return true; } return false; }
/** * create an iterator over a transaction database directory * @param logDir the transaction database directory * @param zxid the zxid to start reading from * @throws IOException */ public FileTxnIterator(File logDir, long zxid) throws IOException { this.logDir = logDir; this.zxid = zxid; init(); }
/** * start reading all the transactions from the given zxid * @param zxid the zxid to start reading transactions from * @return returns an iterator to iterate through the transaction * logs */ public TxnIterator read(long zxid) throws IOException { return new FileTxnIterator(logDir, zxid); }
/** * the dbid of this transaction database * @return the dbid of this database */ public long getDbId() throws IOException { FileTxnIterator itr = new FileTxnIterator(logDir, 0); FileHeader fh=readHeader(itr.logFile); itr.close(); if(fh==null) throw new IOException("Unsupported Format."); return fh.getDbid(); }
Checksum crc = makeChecksumAlgorithm(); crc.update(bytes, 0, bytes.length); if (crcValue != crc.getValue()) if (!goToNextLog()) { return false; return next(); } catch (IOException e) { inputStream.close();
Checksum crc = makeChecksumAlgorithm(); crc.update(bytes, 0, bytes.length); if (crcValue != crc.getValue()) if (!goToNextLog()) { return false; return next(); } catch (IOException e) { inputStream.close();
/** * Invoked to indicate that the input stream has been created. * @param ia input archive * @param is file input stream associated with the input archive. * @throws IOException **/ protected InputArchive createInputArchive(File logFile) throws IOException { if(inputStream==null){ inputStream= new PositionInputStream(new BufferedInputStream(new FileInputStream(logFile))); LOG.debug("Created new input stream " + logFile); ia = BinaryInputArchive.getArchive(inputStream); inStreamCreated(ia,inputStream); LOG.debug("Created new input archive " + logFile); } return ia; }
@Test public void testPreAllocSizeSmallerThanTxnData() throws IOException { File logDir = ClientBase.createTmpDir(); FileTxnLog fileTxnLog = new FileTxnLog(logDir); // Set a small preAllocSize (.5 MB) final int preAllocSize = 500 * KB; FilePadding.setPreallocSize(preAllocSize); // Create dummy txn larger than preAllocSize // Since the file padding inserts a 0, we will fill the data with 0xff to ensure we corrupt the data if we put the 0 in the data byte[] data = new byte[2 * preAllocSize]; Arrays.fill(data, (byte) 0xff); // Append and commit 2 transactions to the log // Prior to ZOOKEEPER-2249, attempting to pad in association with the second transaction will corrupt the first fileTxnLog.append(new TxnHeader(1, 1, 1, 1, ZooDefs.OpCode.create), new CreateTxn("/testPreAllocSizeSmallerThanTxnData1", data, ZooDefs.Ids.OPEN_ACL_UNSAFE, false, 0)); fileTxnLog.commit(); fileTxnLog.append(new TxnHeader(1, 1, 2, 2, ZooDefs.OpCode.create), new CreateTxn("/testPreAllocSizeSmallerThanTxnData2", new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, false, 0)); fileTxnLog.commit(); fileTxnLog.close(); // Read the log back from disk, this will throw a java.io.IOException: CRC check failed prior to ZOOKEEPER-2249 FileTxnLog.FileTxnIterator fileTxnIterator = new FileTxnLog.FileTxnIterator(logDir, 0); // Verify the data in the first transaction CreateTxn createTxn = (CreateTxn) fileTxnIterator.getTxn(); Assert.assertTrue(Arrays.equals(createTxn.getData(), data)); // Verify the data in the second transaction fileTxnIterator.next(); createTxn = (CreateTxn) fileTxnIterator.getTxn(); Assert.assertTrue(Arrays.equals(createTxn.getData(), new byte[]{})); }
/** * truncate the current transaction logs * @param zxid the zxid to truncate the logs to * @return true if successful false if not */ public boolean truncate(long zxid) throws IOException { FileTxnIterator itr = null; try { itr = new FileTxnIterator(this.logDir, zxid); PositionInputStream input = itr.inputStream; if(input == null) { throw new IOException("No log files found to truncate! This could " + "happen if you still have snapshots from an old setup or " + "log files were deleted accidentally or dataLogDir was changed in zoo.cfg."); } long pos = input.getPosition(); // now, truncate at the current position RandomAccessFile raf=new RandomAccessFile(itr.logFile,"rw"); raf.setLength(pos); raf.close(); while(itr.goToNextLog()) { if (!itr.logFile.delete()) { LOG.warn("Unable to truncate {}", itr.logFile); } } } finally { close(itr); } return true; }
/** * start reading all the transactions from the given zxid * @param zxid the zxid to start reading transactions from * @return returns an iterator to iterate through the transaction * logs */ public TxnIterator read(long zxid) throws IOException { return new FileTxnIterator(logDir, zxid); }
/** * the dbid of this transaction database * @return the dbid of this database */ public long getDbId() throws IOException { FileTxnIterator itr = new FileTxnIterator(logDir, 0); FileHeader fh=readHeader(itr.logFile); itr.close(); if(fh==null) throw new IOException("Unsupported Format."); return fh.getDbid(); }
/** * go to the next logfile * @return true if there is one and false if there is no * new file to be read * @throws IOException */ private boolean goToNextLog() throws IOException { if (storedFiles.size() > 0) { this.logFile = storedFiles.remove(storedFiles.size()-1); ia = createInputArchive(this.logFile); return true; } return false; }
/** * initialize to the zxid specified * this is inclusive of the zxid * @throws IOException */ void init() throws IOException { storedFiles = new ArrayList<File>(); List<File> files = Util.sortDataDir(FileTxnLog.getLogFiles(logDir.listFiles(), 0), LOG_FILE_PREFIX, false); for (File f: files) { if (Util.getZxidFromName(f.getName(), LOG_FILE_PREFIX) >= zxid) { storedFiles.add(f); } // add the last logfile that is less than the zxid else if (Util.getZxidFromName(f.getName(), LOG_FILE_PREFIX) < zxid) { storedFiles.add(f); break; } } goToNextLog(); next(); }