You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by mi...@apache.org on 2006/01/29 23:51:54 UTC

svn commit: r373380 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/store/raw/log/ engine/org/apache/derby/impl/store/raw/ engine/org/apache/derby/impl/store/raw/data/ engine/org/apache/derby/impl/store/raw/log/ engine/org/apache/derby/loc...

Author: mikem
Date: Sun Jan 29 14:51:42 2006
New Revision: 373380

URL: http://svn.apache.org/viewcvs?rev=373380&view=rev
Log:
Derby-239, onlinebackup_8.diff patch
committed on behalf of Suresh Thalamati

This patch addresses the improvements suggested by Oystein in his review of the
first online backup patch(onlinebackup_1.diff) and also resolved some more
online backup issues.

-- fixed comments and moved a duplicate code in write page and the backup of
container into a separate method.

fixes with this patch:

-- backup of container was using the same encryption buffer as container
read/writes, this requires backup of the container and read/writes are
synchronized to avoid corrupting the encryption buffer. This patch modified
the backup of container code to use it's own temporary encryption
buffer to avoid the buffer corruption.

-- added code to prevent truncation of log during checkpoint and disabling of
log archival does not delete log files that are yet to be copied
into the backup, if backup is running in parallel.

-- In-place compress is blocked during backup and vice-versa, until the
compress nested transaction commits. This change is needed because compress
does a special checkpoint to avoid redo on the truncated pages. If backup is
running in parallel, the checkpoint backup is based on can be earlier than
checkpoint done by the truncate operation. Without the blocking during
restore from backup, recovery will fail if it needs redo ant log records on
the truncated pages. 


Added:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/onlineBackupTest4.out
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/onlineBackupTest4.sql
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/onlineBackupTest4_app.properties
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/log/LogFactory.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/RawStore.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseContainer.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseContainerHandle.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/InputStreamContainer.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/LogToFile.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/ReadOnly.java
    db/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties
    db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storemore.runall
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/log/LogFactory.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/log/LogFactory.java?rev=373380&r1=373379&r2=373380&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/log/LogFactory.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/store/raw/log/LogFactory.java Sun Jan 29 14:51:42 2006
@@ -260,9 +260,8 @@
 	 * to bring the database to the consistent state on restore. 
 	 * copies the log control information , active log files to the given 
 	 * backup directory and marks that backup is in progress.
-	 @param toDir - location where the log files should be copied to.
-	 @return true if log files copy is  successful
-	 @exception StandardException - encounter exception while doing checkpoint.
+     * @param toDir - location where the log files should be copied to.
+     * @exception StandardException Standard Derby error policy
 	*/
 	public void startLogBackup(File toDir) throws StandardException;
 
@@ -270,9 +269,8 @@
 	/*
 	 * copy all the log files that has to go into the backup directory
 	 * and mark that backup has come to an end. 
-	 @param toDir - location where the log files should be copied to.
-	 @return true if log files copy is  successful
-	 @exception StandardException - encounter exception while doing checkpoint.
+     * @param toDir - location where the log files should be copied to.
+     * @exception StandardException Standard Derby error policy
 	*/
 	public void endLogBackup(File toDir) throws StandardException;
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/RawStore.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/RawStore.java?rev=373380&r1=373379&r2=373380&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/RawStore.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/RawStore.java Sun Jan 29 14:51:42 2006
@@ -98,8 +98,16 @@
 public final class RawStore implements RawStoreFactory, ModuleControl, ModuleSupportable, PrivilegedExceptionAction
 {
 	private static final String BACKUP_HISTORY = "BACKUP.HISTORY";
+    
+    // files that should not be copied into the backup using simple 
+    // directory copy or not needed in the backup at all. 
 	private static final String[] BACKUP_FILTER =
-	{ DataFactory.TEMP_SEGMENT_NAME, DataFactory.DB_LOCKFILE_NAME, DataFactory.DB_EX_LOCKFILE_NAME, LogFactory.LOG_DIRECTORY_NAME, "seg0" };
+	{ DataFactory.TEMP_SEGMENT_NAME,    // not required to be in the backup
+      DataFactory.DB_LOCKFILE_NAME,     // not required to be in the backup
+      DataFactory.DB_EX_LOCKFILE_NAME,  // not required to be in the backup
+      LogFactory.LOG_DIRECTORY_NAME,    // written to the backup using log factory
+      "seg0"                            // written to the backup using data factory
+    };
 
 	protected TransactionFactory	xactFactory;
 	protected DataFactory			dataFactory;
@@ -471,7 +479,7 @@
 
     /**
      * Backup the database to a backup directory.
-     * 
+     *
      * @param backupDir the name of the directory where the backup should be
      *                  stored. This directory will be created if it 
      *                  does not exist.
@@ -547,11 +555,11 @@
      * Transaction log is also backed up, this is used to bring the database to 
      * the consistent state on restore.
 	 * 
-	 * TODO : make sure no parallel backup/disabling log archive mode occurs.
+     * <P> MT- only one thread  is allowed to perform backup at any given time. 
+     *  Synchronized on this. Parallel backups are not supported. 
 	 */
-	public synchronized void backup(
-    Transaction t, 
-    File        backupDir) 
+	public synchronized void backup(Transaction t, 
+                                    File backupDir) 
         throws StandardException
 	{
         if (!privExists(backupDir))
@@ -631,8 +639,12 @@
 			}
 
 
-			// copy everything from the dataDirectory to the
-			// backup directory (except temp files, log , seg0 (see BACKUP_FILTER)
+            // copy the files that does not need any special handling and are 
+            // needed to be in the database directory to the backup directory. 
+            // See BACKUP_FILTER for all the files that are not copied 
+            // to the database directory by the call below. After this copy 
+            // information from log(transaction log), seg0(data segment)   has 
+            // to be copied into the backup from the database.
 			
             if (!privCopyDirectory(dbase, backupcopy, (byte[])null, BACKUP_FILTER))
             {
@@ -855,14 +867,24 @@
 	}
 
 
-	public synchronized void disableLogArchiveMode(boolean deleteOnlineArchivedLogFiles)
+    /*
+     * Disable the log archive mode and delete the archived log files 
+     * if requested. 
+     *
+     * @param deleteOnlineArchivedLogFiles  
+     *              If true deletes online archived 
+     *              log files that exist before this backup, delete 
+     *              will occur  only after the backup is  complete.
+     * @exception StandardException thrown on error.
+     */
+	public void disableLogArchiveMode(boolean deleteOnlineArchivedLogFiles)
 		throws StandardException
 	{
 		logFactory.disableLogArchiveMode();
 		if(deleteOnlineArchivedLogFiles)
 		{
-			logFactory.deleteOnlineArchivedLogFiles();
-		}
+            logFactory.deleteOnlineArchivedLogFiles();
+        }
 	}
 
 	

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseContainer.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseContainer.java?rev=373380&r1=373379&r2=373380&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseContainer.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseContainer.java Sun Jan 29 14:51:42 2006
@@ -823,9 +823,12 @@
 	public abstract long getEstimatedPageCount(BaseContainerHandle handle, int flag) throws StandardException;
 
 	/**
-	   Backup the container to the specified path.
-	   @exception StandardException	Standard Cloudscape error policy
-	*/
+     * Backup the container to the specified path.
+     * 
+     * @param handle the container handle.
+     * @param backupConatainerPath  location of the backup container. 
+     * @exception StandardException Standard Derby error policy 
+     */
 	protected abstract void  backupContainer(BaseContainerHandle handle, 
 											 String backupContainerPath) throws StandardException ;
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseContainerHandle.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseContainerHandle.java?rev=373380&r1=373379&r2=373380&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseContainerHandle.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/BaseContainerHandle.java Sun Jan 29 14:51:42 2006
@@ -973,9 +973,10 @@
 
 
 	/**
-	   Backup the container to the specified path.
-	   @exception StandardException	Standard Cloudscape error policy
-	*/
+     * Backup the container to the specified path.
+     * @param backupConatainerPath  location of the backup container.
+	 *  @exception StandardException	Standard Derby error policy
+     */
 	public void backupContainer(String backupContainerPath) throws StandardException 
     {
 		checkOpen();

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java?rev=373380&r1=373379&r2=373380&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java Sun Jan 29 14:51:42 2006
@@ -1351,12 +1351,19 @@
 			return;
         }
 
+        
         // make sure we don't execute redo recovery on any page
         // which is getting truncated.  At this point we have an exclusive
         // table lock on the table, so after checkpoint no page change
         // can happen between checkpoint log record and compress of space.
         dataFactory.getRawStoreFactory().checkpoint();
 
+        // block the backup, If backup is already in progress wait 
+        // for the backup to finish. Otherwise restore from the backup
+        // can start recovery at different checkpoint and possibly
+        // do redo on pages that are going to get truncated.
+        ntt.blockBackup(true);
+
 		try
 		{
             synchronized(allocCache)
@@ -2798,13 +2805,18 @@
 
 	/** 
 	 *  Get a latched page to write to the backup. Page Latch is necessary to 
-	 *  to prevent modification to the page when it is being backedup.
+	 *  prevent modification to the page when it is being written to the backup.
 	 *  Backup process relies on latches to get consistent snap
 	 *  shot of the page , user level table/page/row locks are NOT 
 	 *  acquired  by the online backup mechanism.
-	 *	@exception StandardException Cloudscape Standard error policy
+     *
+     *  @param handle the container handle used to latch the page
+     *  @param pageNumber the page number of the page to get
+     *  @return the latched page
+	 *	@exception StandardException Standard Derby error policy
 	 */
-	protected BasePage getPageForBackup(BaseContainerHandle handle, long pageNumber) 
+	protected BasePage getPageForBackup(BaseContainerHandle handle, 
+                                        long pageNumber) 
 		throws StandardException 
 	{
 		PageKey pageKey = new PageKey(identity, pageNumber);
@@ -2980,16 +2992,15 @@
 
 		@exception StandardException Standard Cloudscape error policy
 	 */
-	protected byte[] encryptPage(byte[] pageData, int pageSize)
-		 throws StandardException
+	protected byte[] encryptPage(byte[] pageData, 
+                                 int pageSize, 
+                                 byte[] encryptionBuffer)
+        throws StandardException
 	{
 		// because all our page header looks identical, move the
 		// checksum to the front so that it will hopefully encrypt
 		// differently from page to page
 
-		if (encryptionBuffer == null || encryptionBuffer.length < pageSize)
-			encryptionBuffer = new byte[pageSize];
-
 		System.arraycopy(pageData, pageSize-8, encryptionBuffer, 0, 8);
 		System.arraycopy(pageData, 0, encryptionBuffer, 8, pageSize-8);
 
@@ -3004,6 +3015,21 @@
 	}
 
 
+    /** 
+     * Get encryption buffer.
+     *  MT - not safe, call within synchronized block and only use the
+     *  returned byte array withing synchronized block. 
+     * @return byte array to be used for encryping a page.
+     */
+    protected byte[] getEncryptionBuffer() {
+
+        if (encryptionBuffer == null || encryptionBuffer.length < pageSize)
+			encryptionBuffer = new byte[pageSize];
+        return encryptionBuffer;
+    }
+    
+    
+
 	/*
 	 * page preallocation
 	 */
@@ -3211,9 +3237,13 @@
 
 
 	/**
-	   backup the container.
-	   @exception StandardException Standard Cloudscape error policy 
-	*/
-	protected abstract void backupContainer(BaseContainerHandle handle,	String backupLocation)
+     * backup the container.
+     * 
+     * @param handle the container handle.
+     * @param backupLocation location of the backup container. 
+     * @exception StandardException Standard Derby error policy 
+     */
+	protected abstract void backupContainer(BaseContainerHandle handle,	
+                                            String backupLocation)
 	    throws StandardException;
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/InputStreamContainer.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/InputStreamContainer.java?rev=373380&r1=373379&r2=373380&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/InputStreamContainer.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/InputStreamContainer.java Sun Jan 29 14:51:42 2006
@@ -236,15 +236,18 @@
 
 		
 	/**
-	   backup the container.
-	   @exception StandardException Standard Cloudscape error policy 
-	*/
+     * Backup the container.
+     * There is no support to backup this type of containers. It may not be any
+     * real use for users because users can simply  make copies of the read only 
+     * database in Zip files easily using OS utilities.
+     * 
+     * @exception StandardException Standard Derby error policy 
+     */
 	protected void backupContainer(BaseContainerHandle handle,	String backupLocation)
 	    throws StandardException
 	{
-		// Nothing to do; No one would want to do a  backup of a readonly datbase. 
-		// RESOLVE: make sure some where this case is handled and 
-		// users sees a right error message.
+        throw StandardException.newException(
+                SQLState.STORE_FEATURE_NOT_IMPLEMENTED);
 	}
 
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer.java?rev=373380&r1=373379&r2=373380&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer.java Sun Jan 29 14:51:42 2006
@@ -357,24 +357,6 @@
 			if (getCommittedDropState())
 				return;
 
-			if (pageNumber == FIRST_ALLOC_PAGE_NUMBER)
-			{
-				// write header into the alloc page array regardless of dirty
-				// bit because the alloc page have zero'ed out the borrowed
-				// space
-				writeHeader(pageData);
-
-				if (SanityManager.DEBUG) {
-					if (FormatIdUtil.readFormatIdInteger(pageData) != AllocPage.FORMAT_NUMBER)
-						SanityManager.THROWASSERT(
-							"expect " +
-							AllocPage.FORMAT_NUMBER +
-							"got " +
-							FormatIdUtil.readFormatIdInteger(pageData));
-				}
-
-			}
-
 		///////////////////////////////////////////////////
 		//
 		// RESOLVE: right now, no logical -> physical mapping.
@@ -398,19 +380,21 @@
 				if (fileData.getFilePointer() != pageOffset)
 					padFile(fileData, pageOffset);
 
-				byte[] dataToWrite;
-
-				if (dataFactory.databaseEncrypted() 
+                byte [] encryptionBuf = null; 
+                if (dataFactory.databaseEncrypted() 
 					&& pageNumber != FIRST_ALLOC_PAGE_NUMBER)
 				{
 					// We cannot encrypt the page in place because pageData is
 					// still being accessed as clear text.  The encryption
 					// buffer is shared by all who access this container and can
 					// only be used within the synchronized block.
-					dataToWrite = encryptPage(pageData, pageSize);
-				} else {
-					dataToWrite = pageData;
-				}
+
+                    encryptionBuf = getEncryptionBuffer();
+                }
+
+				byte[] dataToWrite = updatePageArray(pageNumber, 
+                                                     pageData, 
+                                                     encryptionBuf);
 
 				dataFactory.writeInProgress();
 				try
@@ -471,6 +455,49 @@
 
 	}
 
+    /**
+     * Update the page array with container header if the page is a first alloc
+     * page and encrypt the page data if the database is encrypted.  
+     * @param pageNumber the page number of the page
+     * @param pageData  byte array that has the actual page data.
+     * @param encryptionBuf buffer that is used to store encryted version of the
+     * page.
+     * @return byte array of the the page data as it should be on the disk.
+     */
+    private byte[] updatePageArray(long pageNumber, 
+                                   byte[] pageData, 
+                                   byte[] encryptionBuf) 
+        throws StandardException, IOException
+    {
+        if (pageNumber == FIRST_ALLOC_PAGE_NUMBER)
+        {
+            // write header into the alloc page array regardless of dirty
+            // bit because the alloc page have zero'ed out the borrowed
+            // space
+            writeHeader(pageData);
+
+            if (SanityManager.DEBUG) {
+                if (FormatIdUtil.readFormatIdInteger(pageData) != AllocPage.FORMAT_NUMBER)
+                    SanityManager.THROWASSERT(
+                            "expect " +
+                            AllocPage.FORMAT_NUMBER +
+                            "got " +
+                            FormatIdUtil.readFormatIdInteger(pageData));
+            }
+
+            return pageData;
+
+        } else 
+        {
+            if (dataFactory.databaseEncrypted()) 
+           {
+                return encryptPage(pageData, pageSize, encryptionBuf);
+            } else
+                return pageData;
+        }
+    }
+
+
 	/**
 		Pad the file upto the passed in page offset.
 		Returns true if the file needed padding.
@@ -672,19 +699,6 @@
 
         synchronized(this)
         {
-			// wait until the thread that is doing the backup completes it
-			// before truncting the container. 
-			while(inBackup)
-			{
-				try	{
-					wait();
-				}
-				catch (InterruptedException ie)
-				{
-					throw StandardException.interrupt(ie);
-				}	
-			}
-
             boolean inwrite = false;
             try
             {
@@ -986,10 +1000,13 @@
 
 
 		
-	/**
-	   backup the  container.
-	   @exception StandardException Standard Cloudscape error policy 
-	*/
+    /**
+     * Backup the  container.
+     * 
+     * @param handle the container handle.
+     * @param backupLocation location of the backup container. 
+     * @exception StandardException Standard Derby error policy 
+     */
 	protected void backupContainer(BaseContainerHandle handle,	String backupLocation)
 	    throws StandardException 
 	{
@@ -1008,203 +1025,203 @@
         }
 	}
 
-	/**
-	 * Backup the  container.
-	 *
-	 * The container is backed up by reading all the pages through the page cache,
-	 * and then writing to the backup container if it not a committed drop
-	 * container. If the container is commited dropped one, stub is copied
-	 * to the backup using simple file copy. 
-	 *
-	 * MT scenarios:
-	 * 1) Remove and backup running in parallel thread:
-	 * The trickey case is if a request to remove the container(because of a
-	 * commited drop) comes when the conatiner backup is in progress. 
+
+    /**
+     * Backup the  container.
+     *
+     * The container is written to the backup by reading  the pages
+     * through the page cache, and then writing into the backup container.
+     * If the container is dropped(commitetd drop), only container stub is
+     * copied to the  backup using simple file copy. 
+     * 
+     * MT - 
+     * At any given time only one backup thread is allowed, but when backup in 
+     * progress DML/DDL operations can run in parallel. Pages are latched while 
+     * writing them to the backup to avoid copying partial changes to the pages.
+     * Online backup does not acquire any user level locks , so users can drop
+     * tables when backup is in progress. So it is possible that Container 
+     * Removal request can come in when container backup is in progress.  
 	 * This case is handled by using the synchronization on this object monitor 
-	 * and using inRemove and inBackup flags.  Basic idea is to give 
-	 * preference to remove by stopping the backup of the container temporarily,
-	 * when  the remove container is requested by another thread. Generally,  it takes
-	 * more  time to backup a regular container than the stub becuase 
-	 * stub is just one page. After each page copy, a check is made to find 
-	 * if a remove is requested and if it is then backup of the container is
-	 * aborted and the backup thread puts itself into the wait state until
+	 * and using inRemove and inBackup flags. Conatiner removal checks if backup
+     * is in progress and wait for the backup to yield to continue the removal. 
+     * Basic idea is to give preference to remove by stopping the backup of the 
+     * container temporarily,  when the remove container is requested by another 
+     * thread. Generally, it takes more  time to backup a regular container than 
+     * the stub becuase  stub is just one page. After each page copy, a check is
+     * made to find  if a remove is requested and if it is then backup of the 
+     * container is aborted and the backup thread puts itself into the wait state until
 	 * remove  request thread notifies that the remove is complete. When 
-	 * remove request compeletes stub is copies into the backup.
-	 * 
-	 * 2) Truncate and backup running in parallel:
-	 * Truncate will wait if the backup is in progress. Truncate does not
-	 * release the montitor until it is complete , backup can not start 
-	 * until it acquires, so if truncate is running, it has to release
-	 * the monitor before backup can proceed.
+	 * remove request compeletes stub is copied into the backup.
 	 * 
- 	 * @exception StandardException Standard Cloudscape error policy 
-	*/
-	private void privBackupContainer(BaseContainerHandle handle,	String backupLocation)
-	    throws StandardException 
-	{
-		boolean done = true;
-		File backupFile = null;
-		RandomAccessFile backupRaf = null;
-		boolean isStub = false;
-		do {
-			try {
-
-				synchronized (this) {
-					// wait if some one is removing the container because of a drop.
-					while (inRemove)
-					{
-						try	{
-							wait();
-						}
-						catch (InterruptedException ie)
-						{
-							throw StandardException.interrupt(ie);
-						}	
-					}
+     * Compress is blocked when backup is in progesss, so truncation of the
+     * container can not happen when backup is in progess. No need to
+     * synchronize backup of the container with truncation. 
+     * 
+     * 
+     * @param handle the container handle.
+     * @param backupLocation location of the backup container. 
+     * @exception StandardException Derby Standard error policy
+     *
+     */
+    private void privBackupContainer(BaseContainerHandle handle,	
+                                     String backupLocation)
+        throws StandardException 
+    {
+        boolean backupCompleted = false;
+        File backupFile = null;
+        RandomAccessFile backupRaf = null;
+        boolean isStub = false;
+        BasePage page = null; 
+
+        while(!backupCompleted) {
+            try {
+
+                synchronized (this) {
+                    // wait if some one is removing the 
+                    // container because of a drop.
+                    while (inRemove)
+                    {
+                        try	{
+                            wait();
+                        }
+                        catch (InterruptedException ie)
+                        {
+                            throw StandardException.interrupt(ie);
+                        }	
+                    }
 
-					if (getCommittedDropState())
-						isStub = true;
-					inBackup = true;
-				}
+                    if (getCommittedDropState())
+                        isStub = true;
+                    inBackup = true;
+                }
 			
-				// create container at the backup location.
-				if (isStub) {
-					// get the stub ( it is a committted drop table container )
-					StorageFile file = privGetFileName((ContainerKey)getIdentity(), true, false, true);
-					backupFile = new File(backupLocation, file.getName());
+                // create container at the backup location.
+                if (isStub) {
+                    // get the stub ( it is a committted drop table container )
+                    StorageFile file = privGetFileName((ContainerKey)getIdentity(), 
+                                                       true, false, true);
+                    backupFile = new File(backupLocation, file.getName());
 
 					// directly copy the stub to the backup 
-					if(!FileUtil.copyFile(dataFactory.getStorageFactory(), file, backupFile))
-					{
-						throw StandardException.newException(SQLState.RAWSTORE_ERROR_COPYING_FILE,
-															 file, backupFile);
-					}
-				} else {
-					// regular container file 
-					StorageFile file = privGetFileName((ContainerKey)getIdentity(), false, false, true);
-					try{
-						backupFile = new File(backupLocation , file.getName());
-						backupRaf = new RandomAccessFile(backupFile,  "rw");
-					} catch (IOException ioe) {
-						throw StandardException.newException( SQLState.FILE_CREATE, ioe, backupFile);
-					}
+					if(!FileUtil.copyFile(dataFactory.getStorageFactory(), 
+                                          file, backupFile))
+                    {
+                        throw StandardException.newException(
+                                              SQLState.RAWSTORE_ERROR_COPYING_FILE,
+                                              file, backupFile);
+                    }
+                }else {
+                    // regular container file 
+                    StorageFile file = privGetFileName((ContainerKey)getIdentity(), 
+                                                       false, false, true);
+                    backupFile = new File(backupLocation , file.getName());
+                    backupRaf = new RandomAccessFile(backupFile,  "rw");
+
+					// copy all the pages of the container from the database 
+                    // to the backup location by reading through the page cache.
+                    
+                    long lastPageNumber= getLastPageNumber(handle);
+
+                    byte[] encryptionBuf = null;
+                    if (dataFactory.databaseEncrypted()) {
+                        // Backup uses seperate encryption buffer to encrypt the
+                        // page instead of encryption buffer used by the regular conatiner
+                        // writes. Otherwise writes to the backup 
+                        // has to be synchronized with regualar database writes
+                        // because backup can run in parallel to container
+                        // writes.
+                        encryptionBuf = new byte[pageSize];
+                    }
 
-					// copy all the pages of the container from the database to the
-					// backup location by reading through the pahe cache.
-				
-					long lastPageNumber= getLastPageNumber(handle);
-					for (long pageNumber = FIRST_ALLOC_PAGE_NUMBER; 
-						 pageNumber <= lastPageNumber; pageNumber++) {
-						BasePage page = getPageForBackup(handle, pageNumber);
-						byte[] pageData = page.getPageArray();
-						writeToBackup(backupRaf, pageNumber, pageData);
-						// unlatch releases page from cache, see StoredPage.releaseExclusive()
-						page.unlatch();
-
-						// check if some one wants to commit drop the table while
-						// being backedup. If so, abort the backup and restart it 
-						// once the drop is complete.
+                    for (long pageNumber = FIRST_ALLOC_PAGE_NUMBER; 
+                         pageNumber <= lastPageNumber; pageNumber++) {
+                        page = getPageForBackup(handle, pageNumber);
+                        
+                        // update the page array before writing to the disk 
+                        // with container header and encrypt it if the database 
+                        // is encrypted. 
+                        
+                        byte[] dataToWrite = updatePageArray(pageNumber, 
+                                                             page.getPageArray(), 
+                                                             encryptionBuf);
+                        backupRaf.write(dataToWrite, 0, pageSize);
+
+                        // unlatch releases page from cache, see 
+                        // StoredPage.releaseExclusive()
+                        page.unlatch();
+                        page = null;
+
+                        // check if some one wants to commit drop the table while
+                        // conatiner is being written to the backup. If so,
+                        // abort  the backup and restart it once the drop 
+                        // is complete.
 
 						synchronized (this)
 						{
 							if (inRemove) {
-								done = false;
-								break;
+								break; 
 							}
 						}
 					}
 				}	
-			} finally {
-				synchronized (this) {
-					inBackup = false;
-					notifyAll();
-				}
-			
-				// if backup of container is not complete, remove the container
-				// from the backup.
-				if (!done && backupFile != null) {
-					if (backupRaf != null) {
-						try {
-							backupRaf.close();
-							backupRaf = null;
-						} catch (IOException ioe){};
-					
-					}
-					if(backupFile.exists())
-						if (!backupFile.delete())
-							throw StandardException.newException(SQLState.UNABLE_TO_DELETE_FILE, 
-																 backupFile);
-				} else {
-					// close the backup conatiner.
-					// incase of a stub, it is already closed 
-					// while doing the copy.
-					if(!isStub) {
-						if (backupRaf != null) {
-							try {
-								backupRaf.getFD().sync();
-								backupRaf.close();
-							} catch (IOException ioe) {
-							} finally {
-								backupRaf = null;
-							}
-						}	
-					}
-				}
-			}
-	
-		} while (!done);
-	}
-
 
-	// write the page to the backup location.
-	private  void writeToBackup(RandomAccessFile backupRaf, long pageNumber, byte[] pageData) 
-		throws StandardException
-	{
-		byte[] dataToWrite;
-		
-		try {
-			if (pageNumber == FIRST_ALLOC_PAGE_NUMBER)
-			{
-				// write header into the alloc page array regardless of dirty
-				// bit because the alloc page have zero'ed out the borrowed
-				// space
-				writeHeader(pageData);
+                // sync and close the backup conatiner. Incase of a stub, 
+                // it is already synced and closed while doing the copy.
+                if(!isStub) {
+                    backupRaf.getFD().sync();
+                    backupRaf.close();
+                    backupRaf = null;
+                }
+                
+                // backup of the conatiner is complete. 
+                backupCompleted = true;
+
+            }catch (IOException ioe) {
+                throw StandardException.newException(
+                                                SQLState.BACKUP_FILE_IO_ERROR, 
+                                                ioe, 
+                                                backupFile);
+            } finally {
+                synchronized (this) {
+                    inBackup = false;
+                    notifyAll();
+                }
 
-				if (SanityManager.DEBUG) {
-					if (FormatIdUtil.readFormatIdInteger(pageData) != AllocPage.FORMAT_NUMBER)
-						SanityManager.THROWASSERT(
-                          "expect " +
-                          AllocPage.FORMAT_NUMBER +
-                          "got " +
-                          FormatIdUtil.readFormatIdInteger(pageData));
-				}
+                if (page != null) {
+                    page.unlatch();
+                    page = null;
+                }
 
-			}
+                // if backup of container is not complete, close the file
+                // handles and  remove the container file from the backup 
+                // if it exists
+                if (!backupCompleted && backupFile != null) 
+                {
+                    if (backupRaf != null) 
+                    {
+						try {
+                            backupRaf.close();
+                            backupRaf = null;
+                        } catch (IOException ioe){
+                            throw StandardException.newException(
+                                            SQLState.BACKUP_FILE_IO_ERROR, 
+                                            ioe, 
+                                            backupFile);
+                        }
+                    }
 
-			if (dataFactory.databaseEncrypted() 
-				&& pageNumber != FIRST_ALLOC_PAGE_NUMBER)
-			{
-				// We cannot encrypt the page in place because pageData is
-				// still being accessed as clear text.  The encryption
-				// buffer is shared by all who access this container and can
-				// only be used within the synchronized block.
-				dataToWrite = encryptPage(pageData, pageSize);
-			} else {
-				dataToWrite = pageData;
-			}
-			
-			long pageOffset = pageNumber * pageSize;
-			backupRaf.seek(pageOffset);
-			backupRaf.write(dataToWrite, 0, pageSize);
+                    if(backupFile.exists()) 
+                    {
+                        if (!backupFile.delete())
+                            throw StandardException.newException(
+                                                SQLState.UNABLE_TO_DELETE_FILE, 
+                                                backupFile);
+                    }
+                } 
+            }
+        }
+    }
 
-		} catch (IOException ioe) {
-			// page cannot be written to the backup
-			throw StandardException.newException(
-                    SQLState.FILE_WRITE_PAGE_EXCEPTION, 
-                    ioe, getIdentity() + ":" + pageNumber);
-		}
-	}
-	
 
      // PrivilegedExceptionAction method
      public Object run() throws StandardException

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/LogToFile.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/LogToFile.java?rev=373380&r1=373379&r2=373380&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/LogToFile.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/LogToFile.java Sun Jan 29 14:51:42 2006
@@ -394,7 +394,7 @@
     // disable syncing of log file when running in derby.system.durability=test
     private boolean logNotSynced = false;
 
-	private boolean logArchived = false;
+	private volatile boolean logArchived = false;
 	private boolean logSwitchRequired = false;
 
 	/** DEBUG test only */
@@ -459,6 +459,14 @@
 	 */
 	private boolean isWriteSynced = false;
 
+    
+    // log file that is yet to be copied to backup, updates to this variable 
+    // needs to visible  checkpoint thread. 
+	private volatile long firstLogFileToBackup ; 
+    // It is set to true when  online backup is in progress,  updates to 
+    // this variable needs to visible to checkpoint thread. 
+    private volatile boolean backupInProgress = false; 
+   
 
 	/**
 		MT- not needed for constructor
@@ -2052,9 +2060,9 @@
 		if ((firstLogNeeded = getFirstLogNeeded(checkpoint))==-1)
 			return;
 		
-		// when  backup is in progress, logfiles should not be deleted 
-		// if they are yet to be backedup, eventhough they are not required
-		// for crash recovery.
+		// when  backup is in progress, Any that are yet to be copied to the
+		// backup should not be deleted,  even if they are
+        // not required  for crash recovery.
 		firstLogNeeded = (backupInProgress ? firstLogFileToBackup : firstLogNeeded);
 		oldFirstLog = firstLogFileNumber;
 		firstLogFileNumber = firstLogNeeded;
@@ -3175,7 +3183,14 @@
 		StorageFile logDir;
 		//find the first  log file number that is  useful
 		long firstLogNeeded = getFirstLogNeeded(currentCheckpoint);
-		if (firstLogNeeded == -1)
+        
+        		
+		// when  backup is in progress, Any that are yet to be copied to the
+		// backup should not be deleted,  even if they are
+        // not required  for crash recovery.
+		firstLogNeeded = (backupInProgress ? firstLogFileToBackup : firstLogNeeded);
+		
+        if (firstLogNeeded == -1)
 			return;
 		try{
 			logDir = getLogDirectory();
@@ -4352,10 +4367,9 @@
 		}
 	}
 
-	//disable the log archive mode
+	// disable the log archive mode
 	public void disableLogArchiveMode() throws StandardException
 	{
-		logArchived = false;
 		AccessFactory af = 
             (AccessFactory)Monitor.getServiceModule(this, AccessFactory.MODULE);
 		if (af != null)
@@ -4364,6 +4378,7 @@
 			tc = af.getTransaction(ContextService.getFactory().getCurrentContextManager());
 			tc.setProperty(Property.LOG_ARCHIVE_MODE , "false", true);
 		}
+        logArchived = false;
 	}
 
 	//delete the online archived log files
@@ -4373,9 +4388,6 @@
 	}
 
 
-	private long firstLogFileToBackup ; //log file that is yet to be backedup
-	private boolean backupInProgress = false; // true if the online backup is in progress
-
 	/*
 	 * start the transaction log backup, transaction log is  is required
 	 * to bring the database to the consistent state on restore. 
@@ -4384,21 +4396,26 @@
 	 * should be kept around until they are copied into the backup,
 	 * even if there are checkpoints when backup is in progress. 
 	 *
-	 * copy the control files to the backup and find first log file 
+	 * copy the log control files to the backup (the checkpoint recorded in the
+     * control files is the backup checkpoint), Restore will use the checkpoint 
+     * info in these control files to perform recovery to bring 
+	 * the database to the consistent state.  and find first log file 
 	 * that need to be copied into the backup to bring the database
 	 * to the consistent state on restore. 
 	 * 
-	 * Log files are copied after all the data files are backed up.
+     * In the end, existing log files that are needed to recover from the backup 
+     * checkpoint are copied into the backup, any log that gets generated after
+     * this call are copied into the backup after all the all the information 
+     * in the data containers is  written to the backup, when endLogBackup() 
+     * is called.
+	 *
+     * @param toDir - location where the log files should be copied to.
+     * @exception StandardException Standard Derby error policy
 	 *
 	 */
 	public void startLogBackup(File toDir) throws StandardException
 	{
 		
-		// copy the checkpoint information into the backup, 
-		// and find the first log file that needs to be be backedup.
-		// Restore will use this checkpoint to perform recovery to bring 
-		// the database to the consistent state.
-		
 		// synchronization is necessary to make sure NO parallel 
 		// checkpoint happens when the current checkpoint information 
 		// is being copied to the backup.
@@ -4451,8 +4468,11 @@
 
 	/*
 	 * copy the log files into the given backup location
+     * @param toDir - location where the log files should be copied to.
+     * @param lastLogFileToBackup - last log file that needs to be copied.
 	 **/
-	private void backupLogFiles(File toDir, long lastLogFileToBackup) throws StandardException
+	private void backupLogFiles(File toDir, long lastLogFileToBackup) 
+        throws StandardException
 	{
 
 		while(firstLogFileToBackup <= lastLogFileToBackup)
@@ -4471,6 +4491,9 @@
 	/*
 	 * copy all the log files that has to go into  the backup
 	 * and mark that backup is compeleted. 
+     *
+     * @param toDir - location where the log files should be copied to.
+     * @exception StandardException Standard Derby error policy
 	 */
 	public void endLogBackup(File toDir) throws StandardException
 	{

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/ReadOnly.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/ReadOnly.java?rev=373380&r1=373379&r2=373380&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/ReadOnly.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/ReadOnly.java Sun Jan 29 14:51:42 2006
@@ -322,13 +322,10 @@
 
 		
 	/*
-	 * start the transaction log backup, the transaction log is  is required
-	 * to bring the database to the consistent state on restore. 
-	 * copies the log control information , active log files to the given 
-	 * backup directory and marks that backup is in progress.
-	 @param toDir - location where the log files should be copied to.
-	 @return true if log files copy is  successful
-	 @exception StandardException - encounter exception while doing checkpoint.
+	 * There are no log files to backup for  read  only databases, nothing to be
+     * done here. 
+     * @param toDir - location where the log files should be copied to.
+     * @exception StandardException Standard Derby error policy
 	*/
 	public void startLogBackup(File toDir) throws StandardException
 	{
@@ -336,12 +333,12 @@
 	}
 
 	
-	/*
-	 * copy all the log files that has to go into the backup directory
-	 * and mark that backup has come to an end. 
-	 @param toDir - location where the log files should be copied to.
-	 @return true if log files copy is  successful
-	 @exception StandardException - encounter exception while doing checkpoint.
+	/* 
+     * There are no log files to backup for read only databases, 
+     * nothing to be done here. 
+     *
+     * @param toDir - location where the log files should be copied to.
+     * @exception StandardException Standard Derby error policy
 	*/
 	public void endLogBackup(File toDir) throws StandardException
 	{
@@ -350,8 +347,8 @@
 
 	
 	/*
-	 * Abort any activity related to backup in the log factory.
-	 * Backup is not in progress any more, it failed for some reason.
+     * Log backup is not started for for read only databases, no work to do
+     * here.
 	 **/
 	public void abortLogBackup()
 	{

Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties?rev=373380&r1=373379&r2=373380&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties Sun Jan 29 14:51:42 2006
@@ -337,6 +337,7 @@
 XSDFB.S=Operation not supported by a read only database
 XSDFD.S=Different page image read on 2 I/Os on Page {0}, first image has incorrect checksum, second image has correct checksum. Page images follows: {1} {2}
 XSDFF.S=The requested operation failed due to an unexpected exception.
+XSDFH.S=Cannot backup the database, got an I/O Exception while writing to the backup container file {0}.
 
 # java/com/ibm/db2j/impl/Database/Storage/RawStore/Data/FileSystem
 # database errors.

Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=373380&r1=373379&r2=373380&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java Sun Jan 29 14:51:42 2006
@@ -502,7 +502,7 @@
 	String FILE_IO_GARBLED                                      = "XSDFD.S";
 	String FILE_UNEXPECTED_EXCEPTION                            = "XSDFF.S";
 	String FILE_ILLEGAL_ENCRYPTED_PAGE_SIZE                     = "XSDFG.S";
-
+    String BACKUP_FILE_IO_ERROR                                 = "XSDFH.S";
 	/*
 	** RawStore - Data.FSLDemo transaction exceptions
 	*/

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/onlineBackupTest4.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/onlineBackupTest4.out?rev=373380&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/onlineBackupTest4.out (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/onlineBackupTest4.out Sun Jan 29 14:51:42 2006
@@ -0,0 +1,80 @@
+ij> -- This script tests online backup functionality and restore. 
+connect 'wombat' as c1 ;
+ij(C1)> connect 'wombat' as c2;
+ij(C2)> set connection c1;
+ij(C1)> autocommit off;
+ij(C1)> -- check backup/restore work with in place compress operation. 
+create table ctest(id int primary key, name char(200)) ;
+0 rows inserted/updated/deleted
+ij(C1)> insert into ctest values(1, 'derby backup/compress test') ;
+1 row inserted/updated/deleted
+ij(C1)> insert into ctest values(2, 'derby backup/compress test') ;
+1 row inserted/updated/deleted
+ij(C1)> insert into ctest select id+2, name from ctest;
+2 rows inserted/updated/deleted
+ij(C1)> insert into ctest select id+4, name from ctest;
+4 rows inserted/updated/deleted
+ij(C1)> insert into ctest select id+8, name from ctest;
+8 rows inserted/updated/deleted
+ij(C1)> insert into ctest select id+16, name from ctest;
+16 rows inserted/updated/deleted
+ij(C1)> insert into ctest select id+32, name from ctest;
+32 rows inserted/updated/deleted
+ij(C1)> insert into ctest select id+64, name from ctest;
+64 rows inserted/updated/deleted
+ij(C1)> insert into ctest select id+128, name from ctest;
+128 rows inserted/updated/deleted
+ij(C1)> insert into ctest select id+256, name from ctest;
+256 rows inserted/updated/deleted
+ij(C1)> commit ;
+ij(C1)> delete from ctest where id > 2 and id < 509 and id != 300;
+505 rows inserted/updated/deleted
+ij(C1)> select * from ctest;
+ID         |NAME                                                                                                                            
+--------------------------------------------------------------------------------------------------------------------------------------------
+1          |derby backup/compress test                                                                                                     &
+2          |derby backup/compress test                                                                                                     &
+300        |derby backup/compress test                                                                                                     &
+509        |derby backup/compress test                                                                                                     &
+510        |derby backup/compress test                                                                                                     &
+511        |derby backup/compress test                                                                                                     &
+512        |derby backup/compress test                                                                                                     &
+ij(C1)> commit;
+ij(C1)> --start backup in a seperare thread.
+set connection c2;
+ij(C2)> async bthread 
+   'call SYSCS_UTIL.SYSCS_BACKUP_DATABASE(''extinout/mybackup'')';
+ij(C2)> -- start compress in seperate thread. 
+set connection c1;
+ij(C1)> async cthread 
+ 'call SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE(''APP'' , 
+                                         ''CTEST'' , 1, 1, 1)';
+ij(C1)> set connection c2;
+ij(C2)> -- wait for backup thread to finish the work.
+wait for bthread;
+0 rows inserted/updated/deleted
+ij(C2)> commit;
+ij(C2)> disconnect;
+ij> set connection c1;
+ij(C1)> -- wait for compress thread to finish the work.
+wait for cthread;
+0 rows inserted/updated/deleted
+ij(C1)> commit;
+ij(C1)> disconnect;
+ij> --shutdown the database
+connect 'wombat;shutdown=true';
+ERROR 08006: Database 'wombat' shutdown.
+ij> connect 'wombat;restoreFrom=extinout/mybackup/wombat';
+ij(CONNECTION1)> select * from ctest;
+ID         |NAME                                                                                                                            
+--------------------------------------------------------------------------------------------------------------------------------------------
+1          |derby backup/compress test                                                                                                     &
+2          |derby backup/compress test                                                                                                     &
+300        |derby backup/compress test                                                                                                     &
+509        |derby backup/compress test                                                                                                     &
+510        |derby backup/compress test                                                                                                     &
+511        |derby backup/compress test                                                                                                     &
+512        |derby backup/compress test                                                                                                     &
+ij(CONNECTION1)> insert into ctest values(2000, 'restore was successfil') ;
+1 row inserted/updated/deleted
+ij(CONNECTION1)> 

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storemore.runall
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storemore.runall?rev=373380&r1=373379&r2=373380&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storemore.runall (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storemore.runall Sun Jan 29 14:51:42 2006
@@ -32,3 +32,4 @@
 store/OnlineBackupTest1.java
 store/onlineBackupTest2.sql
 store/OnlineBackupTest3.java
+store/onlineBackupTest4.sql

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant?rev=373380&r1=373379&r2=373380&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant Sun Jan 29 14:51:42 2006
@@ -148,3 +148,5 @@
 onlineBackupTest2_app.properties
 OnlineBackupTest3_app.properties
 obtest_customer.jar
+onlineBackupTest4.sql
+onlineBackupTest4_app.properties

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/onlineBackupTest4.sql
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/onlineBackupTest4.sql?rev=373380&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/onlineBackupTest4.sql (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/onlineBackupTest4.sql Sun Jan 29 14:51:42 2006
@@ -0,0 +1,54 @@
+-- This script tests online backup functionality and restore. 
+connect 'wombat' as c1 ;
+connect 'wombat' as c2;
+
+set connection c1;
+autocommit off;
+-- check backup/restore work with in place compress operation. 
+create table ctest(id int primary key, name char(200)) ;
+insert into ctest values(1, 'derby backup/compress test') ;
+insert into ctest values(2, 'derby backup/compress test') ;
+insert into ctest select id+2, name from ctest;
+insert into ctest select id+4, name from ctest;
+insert into ctest select id+8, name from ctest;
+insert into ctest select id+16, name from ctest;
+insert into ctest select id+32, name from ctest;
+insert into ctest select id+64, name from ctest;
+insert into ctest select id+128, name from ctest;
+insert into ctest select id+256, name from ctest;
+
+commit ;
+delete from ctest where id > 2 and id < 509 and id != 300;
+select * from ctest;
+commit;
+
+--start backup in a seperare thread.
+set connection c2;
+async bthread 
+   'call SYSCS_UTIL.SYSCS_BACKUP_DATABASE(''extinout/mybackup'')';
+
+-- start compress in seperate thread. 
+set connection c1;
+async cthread 
+ 'call SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE(''APP'' , 
+                                         ''CTEST'' , 1, 1, 1)';
+set connection c2;
+-- wait for backup thread to finish the work.
+wait for bthread;
+commit;
+disconnect;
+
+set connection c1;
+-- wait for compress thread to finish the work.
+wait for cthread;
+commit;
+disconnect;
+
+--shutdown the database
+connect 'wombat;shutdown=true';
+
+connect 'wombat;restoreFrom=extinout/mybackup/wombat';
+select * from ctest;
+insert into ctest values(2000, 'restore was successfil') ;
+
+

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/onlineBackupTest4_app.properties
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/onlineBackupTest4_app.properties?rev=373380&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/onlineBackupTest4_app.properties (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/onlineBackupTest4_app.properties Sun Jan 29 14:51:42 2006
@@ -0,0 +1,5 @@
+usedefaults=true
+useextdirs=true
+
+#exclude with SecurityManager DERBY-709
+noSecurityManager=true