00001 /** 00002 * C-JDBC: Clustered JDBC. 00003 * Copyright (C) 2002-2005 French National Institute For Research In Computer 00004 * Science And Control (INRIA). 00005 * Contact: c-jdbc@objectweb.org 00006 * 00007 * This library is free software; you can redistribute it and/or modify it 00008 * under the terms of the GNU Lesser General Public License as published by the 00009 * Free Software Foundation; either version 2.1 of the License, or any later 00010 * version. 00011 * 00012 * This library is distributed in the hope that it will be useful, but WITHOUT 00013 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00014 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 00015 * for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public License 00018 * along with this library; if not, write to the Free Software Foundation, 00019 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00020 * 00021 * Initial developer(s): Emmanuel Cecchet. 00022 * Contributor(s): Julie Marguerite. 00023 */ 00024 00025 package org.objectweb.cjdbc.controller.recoverylog; 00026 00027 import java.sql.SQLException; 00028 import java.util.ArrayList; 00029 00030 import javax.management.NotCompliantMBeanException; 00031 00032 import org.objectweb.cjdbc.common.i18n.Translate; 00033 import org.objectweb.cjdbc.common.jmx.mbeans.AbstractRecoveryLogMBean; 00034 import org.objectweb.cjdbc.common.log.Trace; 00035 import org.objectweb.cjdbc.common.sql.AbstractWriteRequest; 00036 import org.objectweb.cjdbc.common.sql.StoredProcedure; 00037 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags; 00038 import org.objectweb.cjdbc.common.xml.XmlComponent; 00039 import org.objectweb.cjdbc.controller.jmx.AbstractStandardMBean; 00040 import org.objectweb.cjdbc.controller.requestmanager.TransactionMarkerMetaData; 00041 00042 /** 00043 * Log Recovery is responsible for logging performed queries, managing 00044 * checkpoints and retrieving write requests executed from a given checkpoint. 00045 * 00046 * @author <a href="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a> 00047 * @author <a href="mailto:Julie.Marguerite@inria.fr">Julie Marguerite </a> 00048 * @version 1.0 00049 */ 00050 public abstract class AbstractRecoveryLog extends AbstractStandardMBean 00051 implements 00052 XmlComponent, 00053 AbstractRecoveryLogMBean 00054 { 00055 00056 static Trace logger = Trace 00057 .getLogger("org.objectweb.cjdbc.controller.recoverylog"); 00058 00059 private long recoveringNb = 0; 00060 00061 /** 00062 * Generic constructor. 00063 * 00064 * @param mBeanInterface the MBean interface 00065 * @throws NotCompliantMBeanException if the MBean is not JMX compliant 00066 */ 00067 protected AbstractRecoveryLog(Class mBeanInterface) 00068 throws NotCompliantMBeanException 00069 { 00070 super(mBeanInterface); 00071 } 00072 00073 /** 00074 * Returns the recoveringNb value. 00075 * 00076 * @return Returns the recoveringNb. 00077 */ 00078 public long getRecoveringNb() 00079 { 00080 return recoveringNb; 00081 } 00082 00083 /** 00084 * Log a write request. 00085 * 00086 * @param request The write request to log 00087 * @exception SQLException if an error occurs 00088 */ 00089 public abstract void logRequest(AbstractWriteRequest request) 00090 throws SQLException; 00091 00092 /** 00093 * Log a call to a stored procedure. 00094 * 00095 * @param proc The stored procedure call to log 00096 * @param isRead True if the stored procedure call returns a ResultSet 00097 * @exception SQLException if an error occurs 00098 */ 00099 public abstract void logRequest(StoredProcedure proc, boolean isRead) 00100 throws SQLException; 00101 00102 // 00103 // Transaction management 00104 // 00105 00106 /** 00107 * Get the id of the last transaction logged in the recovery log. 00108 * 00109 * @return the last transaction id. 00110 * @throws SQLException if an error occured while retrieving the id. 00111 */ 00112 public abstract long getLastTransactionId() throws SQLException; 00113 00114 /** 00115 * Log the beginning of a new transaction. 00116 * 00117 * @param tm The transaction marker metadata 00118 * @exception SQLException if an error occurs 00119 */ 00120 public abstract void begin(TransactionMarkerMetaData tm) throws SQLException; 00121 00122 /** 00123 * Log a transaction abort. This is used only for transaction that were 00124 * started but where no request was executed, which is in fact an empty 00125 * transaction. The underlying implementation might safely discard the 00126 * corresponding begin from the log as an optimization. 00127 * 00128 * @param tm The transaction marker metadata 00129 * @exception SQLException if an error occurs 00130 */ 00131 public abstract void abort(TransactionMarkerMetaData tm) throws SQLException; 00132 00133 /** 00134 * Log a transaction commit. 00135 * 00136 * @param tm The transaction marker metadata 00137 * @exception SQLException if an error occurs 00138 */ 00139 public abstract void commit(TransactionMarkerMetaData tm) throws SQLException; 00140 00141 /** 00142 * Log a transaction rollback. 00143 * 00144 * @param tm The transaction marker metadata 00145 * @exception SQLException if an error occurs 00146 */ 00147 public abstract void rollback(TransactionMarkerMetaData tm) 00148 throws SQLException; 00149 00150 // 00151 // Recovery process 00152 // 00153 00154 /** 00155 * Notify the recovery log that a recovery process has started. 00156 */ 00157 public synchronized void beginRecovery() 00158 00159 { 00160 recoveringNb++; 00161 } 00162 00163 /** 00164 * Possibly clean the recovery log after all recovery process are done. 00165 * 00166 * @exception SQLException if an error occurs 00167 */ 00168 public abstract void cleanRecoveryLog() throws SQLException; 00169 00170 /** 00171 * Notify the recovery log that a recovery process has finished. If this is 00172 * the last recovery process to finish, the cleanRecoveryLog method is called 00173 * 00174 * @see #cleanRecoveryLog() 00175 */ 00176 public synchronized void endRecovery() 00177 { 00178 recoveringNb--; 00179 if (recoveringNb == 0) 00180 { 00181 try 00182 { 00183 cleanRecoveryLog(); 00184 } 00185 catch (SQLException e) 00186 { 00187 logger.error(Translate.get("recovery.cleaning.failed", e)); 00188 } 00189 } 00190 } 00191 00192 /** 00193 * Returns <code>true</code> if at least one backend has started a recover 00194 * process. 00195 * 00196 * @return <code>boolean</code> 00197 */ 00198 public synchronized boolean isRecovering() 00199 { 00200 return recoveringNb > 0; 00201 } 00202 00203 /** 00204 * Get the next request (begin/commit/rollback or WriteRequest) from the 00205 * recovery log given the id of the previously recovered request. 00206 * <p> 00207 * The id of the request before the first one to recover is given by 00208 * getCheckpointRequestId. 00209 * 00210 * @param previousRequestId id of the previously recovered request 00211 * @return AbstractTask task corresponding to the next request to recover 00212 * @exception SQLException if an error occurs 00213 * @see #getCheckpointRequestId(String) 00214 */ 00215 public abstract RecoveryTask recoverNextRequest(long previousRequestId) 00216 throws SQLException; 00217 00218 // 00219 // Checkpoint Management 00220 // 00221 00222 /** 00223 * Retrieve recovery information on a backend. This includes, the last known 00224 * state of the backend, and the last known checkpoint 00225 * 00226 * @param databaseName the virtual database name 00227 * @param backendName the backend name 00228 * @return <code>BackendRecoveryInfo<code> instance or <code>null</code> if the backend does not exist 00229 * @throws SQLException if cannot proceed 00230 */ 00231 public abstract BackendRecoveryInfo getBackendRecoveryInfo( 00232 String databaseName, String backendName) throws SQLException; 00233 00234 /** 00235 * Returns an array of names of all the checkpoint available in the recovery 00236 * log 00237 * 00238 * @return <code>ArrayList</code> of <code>String</code> checkpoint names 00239 * @throws SQLException if fails 00240 */ 00241 public abstract ArrayList getCheckpointNames() throws SQLException; 00242 00243 /** 00244 * Get the request id corresponding to a given checkpoint. This is the first 00245 * step in a recovery process. Following steps consist in calling 00246 * recoverNextRequest. 00247 * 00248 * @param checkpointName Name of the checkpoint 00249 * @return int the request identifier corresponding to this checkpoint. 00250 * @exception SQLException if an error occurs 00251 * @see #recoverNextRequest(long) 00252 */ 00253 public abstract long getCheckpointRequestId(String checkpointName) 00254 throws SQLException; 00255 00256 /** 00257 * Remove a checkpoint from the recovery. This is useful for recovery 00258 * maintenant 00259 * 00260 * @param checkpointName to remove 00261 * @throws SQLException if an error occurs 00262 */ 00263 public abstract void removeCheckpoint(String checkpointName) 00264 throws SQLException; 00265 00266 /** 00267 * Store the state of the backend in the recovery log 00268 * 00269 * @param databaseName the virtual database name 00270 * @param backendRecoveryInfo the backend recovery information to store 00271 * @throws SQLException if cannot proceed 00272 */ 00273 public abstract void storeBackendRecoveryInfo(String databaseName, 00274 BackendRecoveryInfo backendRecoveryInfo) throws SQLException; 00275 00276 /** 00277 * Store a Checkpoint using the current log state. 00278 * 00279 * @param checkpointName Name of the checkpoint 00280 * @exception SQLException if an error occurs 00281 */ 00282 public abstract void storeCheckpoint(String checkpointName) 00283 throws SQLException; 00284 00285 /** 00286 * Store a Checkpoint using the given request id. 00287 * 00288 * @param checkpointName Name of the checkpoint 00289 * @param requestId request identifier 00290 * @exception SQLException if an error occurs 00291 */ 00292 public abstract void storeCheckpoint(String checkpointName, long requestId) 00293 throws SQLException; 00294 00295 /** 00296 * Get xml information of the current recovery load in the system. 00297 * 00298 * @return xml formatted string 00299 */ 00300 public String getXml() 00301 00302 { 00303 StringBuffer info = new StringBuffer(); 00304 info.append("<" + DatabasesXmlTags.ELT_RecoveryLog + ">"); 00305 info.append(getXmlImpl()); 00306 info.append("</" + DatabasesXmlTags.ELT_RecoveryLog + ">"); 00307 return info.toString(); 00308 } 00309 00310 /** 00311 * @see org.objectweb.cjdbc.common.xml.XmlComponent#getXml() 00312 */ 00313 public abstract String getXmlImpl(); 00314 00315 /** 00316 * Allow to get the content of the recovery log for viewing 00317 * 00318 * @return <code>String[][]</code> 00319 * @see org.objectweb.cjdbc.console.views.RecoveryLogViewer 00320 */ 00321 public abstract String[][] getData(); 00322 00323 }