KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derbyTesting > functionTests > tests > store > OnlineBackupTest1


1 /*
2
3    Derby - Class org.apache.derbyTesting.functionTests.store.OnlineBackupTest1
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derbyTesting.functionTests.tests.store;
23 import java.sql.Connection JavaDoc;
24 import java.sql.Statement JavaDoc;
25 import java.sql.PreparedStatement JavaDoc;
26 import java.sql.ResultSet JavaDoc;
27 import java.sql.SQLException JavaDoc;
28 import org.apache.derby.tools.ij;
29 import org.apache.derbyTesting.functionTests.util.TestUtil;
30
31 /*
32  * This class tests online backup when dml/ddl actions
33  * are running in parallel to the backup thread.
34  *
35  * @author <a HREF="mailto:suresh.thalamati@gmail.com">Suresh Thalamati</a>
36  * @version 1.0
37  */

38
39 public class OnlineBackupTest1 {
40
41     private static final String JavaDoc TEST_DATABASE_NAME = "wombat" ;
42     private static final String JavaDoc TEST_TABLE_NAME = "emp";
43     private static final String JavaDoc TEST_TABLE_NAME_1 = "emp_1";
44     private static final String JavaDoc TEST_TABLE_NAME_2 = "emp_2";
45     private static final String JavaDoc BACKUP_PATH = "extinout/onlinebackuptest1";
46
47     public static void main(String JavaDoc[] argv) throws Throwable JavaDoc {
48         
49         OnlineBackupTest1 test = new OnlineBackupTest1();
50         ij.getPropertyArg(argv);
51
52         try {
53             test.runTest();
54         }
55         catch (SQLException JavaDoc sqle) {
56             dumpSQLException(sqle);
57         }
58     }
59
60
61     /*
62      * Test online backup with unlogged operations. And DML/DDL's
63      * running in paralel to the backup. After the backup is complete restore
64      * the database from the backup and performs consistency checks on the
65      * database to make sure backup was good one.
66      */

67     private void runTest() throws Exception JavaDoc {
68         logMessage("Begin Online Backup Test1");
69         Connection JavaDoc conn = ij.startJBMS();
70         conn.setAutoCommit(false);
71         DatabaseActions dbActions = new DatabaseActions(conn);
72         //create the test tables.
73
dbActions.createTable(TEST_TABLE_NAME);
74         dbActions.createTable(TEST_TABLE_NAME_1);
75         dbActions.createTable(TEST_TABLE_NAME_2);
76         conn.commit();
77
78         // start first unlogged operation
79
dbActions.startUnloggedAction(TEST_TABLE_NAME_1);
80         logMessage("First Transaction with Unlogged Operation Started");
81
82         // start second unlogged opearation
83
Connection JavaDoc conn1 = ij.startJBMS();
84         conn1.setAutoCommit(false);
85         DatabaseActions dbActions1 = new DatabaseActions(conn1);
86         dbActions1.startUnloggedAction(TEST_TABLE_NAME_2);
87         logMessage("Second Transaction with Unlogged Operation Started");
88
89         // setup threads.
90
// start a thread to perform online backup
91
OnlineBackup backup = new OnlineBackup(TEST_DATABASE_NAME, BACKUP_PATH);
92         Thread JavaDoc backupThread = new Thread JavaDoc(backup, "BACKUP");
93         
94         // run some dml actions in another thread
95
Connection JavaDoc dmlConn = TestUtil.getConnection(TEST_DATABASE_NAME, null);
96         DatabaseActions dmlActions =
97             new DatabaseActions(DatabaseActions.DMLACTIONS, dmlConn);
98         Thread JavaDoc dmlThread = new Thread JavaDoc(dmlActions, "DML_THREAD");
99         
100         // run some DDL create/drop tables in another thread
101
Connection JavaDoc ddlConn = TestUtil.getConnection(TEST_DATABASE_NAME, null);
102         
103         DatabaseActions ddlActions =
104             new DatabaseActions(DatabaseActions.CREATEDROPS, ddlConn);
105         Thread JavaDoc ddlThread = new Thread JavaDoc(ddlActions, "DDL_THREAD");
106
107         try {
108             // start a thread to perform online backup
109
backupThread.start();
110             // wait for the backup to start
111
backup.waitForBackupToBegin();
112             logMessage("BACKUP STARTED");
113
114             // run some dml actions in another thread
115
dmlThread.start();
116
117             // run some DDL create/drop tables in another thread
118
ddlThread.start();
119
120             // sleep for few seconds just to make sure backup thread is actually
121
// gone to a wait state for unlogged actions to commit and there is
122
// some ddl and dml activity in progress.
123
java.lang.Thread.sleep(50000);
124             
125             // backup should not even start doing real work before the
126
// unlogged transaction is commited
127
if(!backup.isRunning())
128                 logMessage("Backup is not waiting for unlogged actions to commit");
129
130             // end the unlogged work transaction.
131
dbActions.endUnloggedAction(TEST_TABLE_NAME_1);
132             // end the unlogged work transaction.
133
dbActions1.endUnloggedAction(TEST_TABLE_NAME_2);
134         
135             backup.waitForBackupToEnd();
136
137         }finally {
138             //stop all threads activities.
139
backupThread.join();
140             dmlActions.stopActivity();
141             ddlActions.stopActivity();
142             dmlThread.join();
143             ddlThread.join();
144         }
145         // close the connections.
146
conn.close();
147         conn1.close();
148         dmlConn.close();
149         ddlConn.close() ;
150
151
152         //shutdown the test db
153
shutdown(TEST_DATABASE_NAME);
154
155         // restore the database from the backup and run some checks
156
backup.restoreFromBackup();
157         logMessage("Restored From the Backup");
158         runConsistencyChecker(TEST_DATABASE_NAME);
159         logMessage("Consistency Check is Done");
160         //shutdown the test db
161
shutdown(TEST_DATABASE_NAME);
162         logMessage("End Online Backup Test1");
163     }
164
165     
166     /**
167      * Run some consistency checks.
168      * @param dbName consistency checks are performed on this database.
169      */

170     void runConsistencyChecker(String JavaDoc dbName) throws SQLException JavaDoc {
171         Connection JavaDoc conn = TestUtil.getConnection(dbName, null);
172         Statement JavaDoc stmt = conn.createStatement();
173         stmt.execute("values SYSCS_UTIL.SYSCS_CHECK_TABLE('APP', 'EMP')");
174         //check the data in the EMP table.
175
DatabaseActions dbActions = new DatabaseActions(conn);
176         dbActions.select(TEST_TABLE_NAME);
177         dbActions.select(TEST_TABLE_NAME_1);
178         dbActions.select(TEST_TABLE_NAME_2);
179         conn.close();
180
181     }
182
183
184         
185     /**
186      * Shutdown the datbase
187      * @param dbName Name of the database to shutdown.
188      */

189     void shutdown(String JavaDoc dbName) {
190
191         try{
192             //shutdown
193
TestUtil.getConnection(dbName, "shutdown=true");
194         }catch(SQLException JavaDoc se){
195             if (se.getSQLState() != null && se.getSQLState().equals("08006"))
196                 System.out.println("database shutdown properly");
197             else
198                 dumpSQLException(se);
199         }
200     }
201
202     /**
203      * Write message to the standard output.
204      */

205     void logMessage(String JavaDoc str) {
206             System.out.println(str);
207     }
208
209     
210     /**
211      * dump the SQLException to the standard output.
212      */

213     static private void dumpSQLException(SQLException JavaDoc sqle) {
214         
215         org.apache.derby.tools.JDBCDisplayUtil. ShowSQLException(System.out, sqle);
216         sqle.printStackTrace(System.out);
217     }
218
219     /*
220      * This class implements some DML and DDL operations to
221      * run againest the datbase, when the backup is in progress.
222      * Some of these operations can be run in seperate threads in a
223      * loop until they are stopped by some other thread.
224      */

225     
226     class DatabaseActions implements Runnable JavaDoc {
227  
228         public static final int DMLACTIONS = 1;
229         public static final int CREATEDROPS = 2;
230
231         private static final int COMMIT = 1;
232         private static final int ROLLBACK = 2;
233         private static final int OPENTX = 3;
234
235         private int action = 0;
236         private volatile boolean stopActivity = false ;
237         private Connection JavaDoc conn;
238     
239         DatabaseActions(Connection JavaDoc conn) {
240             this.conn = conn;
241         };
242
243         DatabaseActions(int action, Connection JavaDoc conn) {
244             this.action = action;
245             this.conn = conn;
246         }
247
248         /**
249          * stops any actions that are looping on a differt threads.
250          */

251         public void stopActivity() {
252             stopActivity = true;
253         }
254
255         /**
256          * implementation of run() method in the Runnable interface, which
257          * is invoked when a thread is started using this class object.
258          * <p>
259          * Performs DML ot DDL actions.
260          */

261          public void run() {
262             try {
263                 conn.setAutoCommit(false);
264                 switch(action) {
265                     case DMLACTIONS :
266                         performDmlActions();
267                         break;
268                     case CREATEDROPS:
269                         performCreateDropTables() ;
270                         break;
271                 }
272             } catch (SQLException JavaDoc sqle) {
273                 org.apache.derby.tools.JDBCDisplayUtil.ShowSQLException(System.out, sqle);
274                 sqle.printStackTrace(System.out);
275             }
276         }
277
278         
279         /*
280          * Run insert, update, select on the test table in a loop.
281          */

282         void performDmlActions() throws SQLException JavaDoc {
283             
284             while(!stopActivity) {
285                 insert(TEST_TABLE_NAME, 100, COMMIT, 10);
286                 insert(TEST_TABLE_NAME, 100, ROLLBACK, 10);
287                 update(TEST_TABLE_NAME, 50, ROLLBACK, 10);
288                 select(TEST_TABLE_NAME);
289             }
290         }
291
292
293         
294         /**
295          * start an Unlogged operation, but don't commit the transaction.
296          * @param tableName name of the table to start the unlogged operation.
297          * @exception SQLException if any database exception occurs.
298          */

299         void startUnloggedAction(String JavaDoc tableName) throws SQLException JavaDoc {
300             // load some data
301
insert(tableName, 100, COMMIT, 10);
302             // execute a unlogged database operation
303
Statement JavaDoc s = conn.createStatement();
304             
305             // index creation does not log the index entries
306
s.executeUpdate("create index " + tableName + "_name_idx on " +
307                             tableName + "(name) ");
308             s.close();
309         }
310
311         
312         /**
313          * end an Unlogged operation, commit the transaction.
314          * @param tableName name of the table to end unlogged operation.
315          * @exception SQLException if any database exception occurs.
316          */

317         void endUnloggedAction(String JavaDoc tableName) throws SQLException JavaDoc {
318             // insert some rows, insert should be successful even if
319
// backup is blocking for uncommitted unlogged operations.
320
insert(tableName, 1000, OPENTX, 10);
321             conn.commit();
322         }
323
324                 
325         /**
326          * Create and Drop some tables.
327          * @exception SQLException if any database exception occurs.
328          */

329         void performCreateDropTables() throws SQLException JavaDoc {
330             
331             Statement JavaDoc s = conn.createStatement();
332             while(!stopActivity) {
333                 for( int i = 0 ; i < 10; i++) {
334                     String JavaDoc tableName = "emp" + i ;
335                     createTable(tableName);
336                     //load some data
337
insert(tableName, 100, OPENTX, 10);
338                     if((i % 2) == 0) {
339                         conn.commit();
340                     }
341                     else
342                         conn.rollback();
343                 }
344
345                 //drop all the table that are created above.
346
for( int i = 0 ; i < 10 ; i=i+2) {
347                     String JavaDoc tableName = "emp" + i ;
348                     s.executeUpdate("drop TABLE " + "emp" +i );
349                     conn.commit();
350                 }
351             }
352             s.close();
353         }
354
355
356         
357         /**
358          * Insert some rows into the specified table.
359          * @param tableName name of the table that rows are inserted.
360          * @param rowCount Number of rows to Insert.
361          * @param txStaus Transacton status commit/rollback/open.
362          * @param commitCount After how many inserts commit/rollbacku should happen.
363          * @exception SQLException if any database exception occurs.
364          */

365         void insert(String JavaDoc tableName, int rowCount,
366                     int txStatus, int commitCount) throws SQLException JavaDoc {
367
368             PreparedStatement JavaDoc ps = conn.prepareStatement("INSERT INTO " +
369                                                          tableName +
370                                                          " VALUES(?,?,?)");
371             for (int i = 0; i < rowCount; i++) {
372             
373                 ps.setInt(1, i); // ID
374
ps.setString(2 , "skywalker" + i);
375                 ps.setFloat(3, (float)(i * 2000));
376                 ps.executeUpdate();
377                 if ((i % commitCount) == 0)
378                 {
379                     endTransaction(txStatus);
380                 }
381             }
382
383             endTransaction(txStatus);
384             ps.close();
385         }
386
387
388
389         /**
390          * commit/rollback the transaction.
391          * @param txStaus Transacton status commit/rollback/open.
392          * @exception SQLException if any database exception occurs.
393          */

394         void endTransaction(int txStatus) throws SQLException JavaDoc
395         {
396             switch(txStatus){
397             case COMMIT:
398                 conn.commit();
399                 break;
400             case ROLLBACK:
401                 conn.rollback();
402                 break;
403             case OPENTX:
404                 //do nothing
405
break;
406             }
407         }
408         
409         /**
410          * update some rows in the table.
411          * @param tableName name of the table that rows are updates.
412          * @param rowCount Number of rows to update.
413          * @param txStaus Transacton status commit/rollback/open.
414          * @param commitCount After how many updates commit/rollback should
415          * happen.
416          * @exception SQLException if any database exception occurs.
417          */

418
419         void update(String JavaDoc tableName, int rowCount,
420                     int txStatus, int commitCount) throws SQLException JavaDoc
421         {
422
423             PreparedStatement JavaDoc ps = conn.prepareStatement("update " + tableName +
424                                  " SET name = ? where id=?");
425         
426             for (int i = 0; i < rowCount; i++) {
427                 ps.setString(1 , "moonwalker" + i);
428                 ps.setInt(2, i); // ID
429
ps.executeUpdate();
430                 if ((i % commitCount) == 0)
431                 {
432                     endTransaction(txStatus);
433                 }
434             }
435             endTransaction(txStatus);
436             ps.close();
437         }
438
439
440         /*
441          * read the rows in the table.
442          * @param tableName select operation is perfomed on this table.
443          * @exception SQLException if any database exception occurs.
444          */

445         void select(String JavaDoc tableName) throws SQLException JavaDoc {
446         
447             Statement JavaDoc s = conn.createStatement();
448             ResultSet JavaDoc rs = s.executeQuery("SELECT ID, name from " +
449                                           tableName + " order by id" );
450             int count = 0;
451             int id = 0;
452             while(rs.next())
453             {
454                 int tid = rs.getInt(1);
455                 String JavaDoc name = rs.getString(2);
456                 if(name.equals("skywalker" + id) && tid!= id)
457                 {
458                     logMessage("DATA IN THE TABLE IS NOT AS EXPECTED");
459                     logMessage("Got :ID=" + tid + " Name=:" + name);
460                     logMessage("Expected: ID=" + id + "Name=" + "skywalker" + id );
461                 }
462
463                 id++;
464                 count++;
465             }
466             
467             rs.close();
468             s.close();
469             conn.commit();
470         }
471
472         /*
473          * create the tables that are used by this test.
474          * @param tableName Name of the table to create.
475          * @exception SQLException if any database exception occurs.
476          */

477         void createTable(String JavaDoc tableName) throws SQLException JavaDoc {
478
479             Statement JavaDoc s = conn.createStatement();
480             s.executeUpdate("CREATE TABLE " + tableName +
481                             "(id INT," +
482                             "name CHAR(200),"+
483                             "salary float)");
484             s.executeUpdate("create index " + tableName + "_id_idx on " +
485                             tableName + "(id)");
486             s.close();
487         }
488
489     }
490 }
491
Popular Tags