1 9 package org.ozoneDB.core.admin; 10 11 import org.ozoneDB.DxLib.DxIterator; 12 import org.ozoneDB.OzoneCompatible; 13 import org.ozoneDB.OzoneInterface; 14 import org.ozoneDB.core.*; 15 import org.ozoneDB.core.xml.*; 16 import org.ozoneDB.util.LogWriter; 17 import org.ozoneDB.xml.util.*; 18 import org.xml.sax.helpers.AttributesImpl ; 19 20 import java.io.*; 21 22 23 35 public class BackupRestore implements XML2ObjectDelegate { 36 37 protected final static String TMP_FILE_NAME = "oids.tmp"; 38 39 protected final static String BACKUP_ELEMENT_NAME = "ozone-database-backup"; 40 41 protected transient Env env; 42 43 protected transient SAXChunkProducer backupProducer; 44 45 protected transient DataInputStream backupIn; 46 47 protected transient SAXChunkConsumer restoreConsumer; 48 49 protected transient int idcount; 50 51 52 public BackupRestore( Env _env ) { 53 env = _env; 54 } 55 56 57 public void beginRestore() throws Exception { 58 env.logWriter.newEntry( this, "beginRestore()...", LogWriter.INFO ); 59 60 if (restoreConsumer != null) { 61 throw new IllegalStateException ( "There is a restore process already in progress." ); 62 } 63 XML2ObjectContentHandler restoreHandler = new XML2ObjectContentHandler( this ); 64 restoreConsumer = new SAXChunkConsumer( restoreHandler ); 65 } 66 67 68 public void processRestoreChunk( byte[] chunk ) throws Exception { 69 if (restoreConsumer == null) { 70 throw new IllegalStateException ( "Start the restore process first." ); 71 } 72 if (chunk == null) { 73 restoreConsumer = null; 74 } 75 else { 76 System.out.println( "" ); 77 env.logWriter.newEntry( this, "processRestoreChunk(): size=" + chunk.length, LogWriter.INFO ); 78 restoreConsumer.processChunk( chunk ); 79 } 80 } 81 82 83 87 public void handleObject( ObjElement element ) { 88 System.out.print( '.' ); 89 90 OzoneCompatible obj = (OzoneCompatible)element.getObject(); 91 ObjectID id = new ObjectID( Long.parseLong( (String )element.getOzoneObjectId() ) ); 92 String name = (String )element.getOzoneObjectName(); 93 94 env.logWriter.newEntry( this, "handleObject(): " + element.getClassName() + ": oid=" + id + ", target=" + obj, LogWriter.DEBUG3 ); 95 96 try { 97 ObjectContainer container = env.transactionManager.currentTA().createObject(null,OzoneInterface.Public,name,null,null,id); 98 99 try { 100 container.setTarget( obj ); 101 } finally { 102 container.unpin(); 103 } 104 } catch (Exception e) { 105 throw new RuntimeException (e); 106 } 107 } 108 109 110 public void beginBackup() throws Exception { 111 if (backupIn != null) { 112 throw new IllegalStateException ( "There is a backup process already in progress." ); 113 } 114 115 backupProducer = new SAXChunkProducer( (SAXChunkProducerDelegate)null ); 116 backupProducer.startDocument(); 117 backupProducer.startElement( "", BACKUP_ELEMENT_NAME, BACKUP_ELEMENT_NAME, new AttributesImpl () ); 118 119 env.logWriter.newEntry( this, "preparing list of object IDs...", LogWriter.INFO ); 120 121 idcount = 0; 122 DataOutputStream out = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( env.getDatabaseDir() + TMP_FILE_NAME ), 4096 ) ); 123 DxIterator backupIt = env.storeManager.objectIDIterator(); 124 while (backupIt.next() != null) { 125 out.writeLong( ((ObjectID)backupIt.key()).value() ); 126 idcount ++; 127 } 128 out.close(); 129 130 env.logWriter.newEntry( this, "preparing list of object IDs... ready. (" + idcount + " IDs)", LogWriter.INFO ); 131 idcount = 0; 132 133 backupIn = new DataInputStream( new BufferedInputStream( new FileInputStream( env.getDatabaseDir() + TMP_FILE_NAME ), 4096 ) ); 134 } 135 136 137 private ObjectID nextBackupID() throws Exception { 138 if (backupIn == null) { 139 throw new IllegalStateException ( "Start backup process first." ); 140 } 141 try { 142 return new ObjectID( backupIn.readLong() ); 143 } 144 catch (Exception e) { 145 backupIn.close(); 146 backupIn = null; 147 new File( env.getDatabaseDir() + TMP_FILE_NAME ).delete(); 148 149 if (e instanceof EOFException) { 150 return null; 151 } else { 152 throw e; 153 } 154 } 155 } 156 157 158 public byte[] nextBackupChunk() throws Exception { 159 Transaction ta = env.transactionManager.currentTA(); 160 if (env.logWriter.hasTarget(LogWriter.DEBUG3)) { 161 env.logWriter.newEntry(this, "current transaction: " + ta, LogWriter.DEBUG3 ); 162 } 163 if (backupProducer == null) { 164 return null; 165 } 166 167 ChunkOutputStream cos = backupProducer.chunkStream(); 168 ObjectID id = null; 169 170 while (cos.getState() != ChunkOutputStream.STATE_OVERFLOW && (id=nextBackupID()) != null) { 172 if (env.logWriter.hasTarget(LogWriter.DEBUG3)) { 173 env.logWriter.newEntry(this, "chunk size: " + cos.size() + " oid: " + id, LogWriter.DEBUG3 ); 174 } 175 176 ObjectContainer container = ta.acquireObject( id, Lock.LEVEL_READ ); 177 178 try { 179 OzoneCompatible target = container.target(); 180 if (env.logWriter.hasTarget(LogWriter.DEBUG3)) { 181 env.logWriter.newEntry(this, "target: " + target + "[" + target.getClass().getName() + "]", LogWriter.DEBUG3 ); 182 } 183 184 if (target instanceof org.ozoneDB.core.admin.AdminImpl) { 185 continue; 186 } 187 188 Object2XML o2x = new Object2XML( backupProducer, true ); 189 o2x.toXML( target ); 190 } finally { 191 container.unpin(); 192 } 193 } 194 195 if (id == null) { 196 backupProducer.endElement( "", BACKUP_ELEMENT_NAME, BACKUP_ELEMENT_NAME ); 197 backupProducer.endDocument(); 198 cos.setEndFlag(); 199 backupProducer = null; 201 } 202 byte[] temp = cos.toByteArray(); 203 cos.reset(); 204 env.logWriter.newEntry( this, "nextBackupChunk(): size=" + temp.length, LogWriter.DEBUG ); 205 return temp; 206 } 207 208 } 209 210 | Popular Tags |