KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derbyTesting.functionTests.harness.procedure
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
24
25 import org.apache.derby.iapi.services.sanity.SanityManager;
26
27 import java.sql.CallableStatement JavaDoc;
28 import java.sql.Connection JavaDoc;
29 import java.sql.PreparedStatement JavaDoc;
30 import java.sql.ResultSet JavaDoc;
31 import java.sql.SQLException JavaDoc;
32 import java.sql.Statement JavaDoc;
33
34 import org.apache.derby.tools.ij;
35
36
37 /**
38
39 The purpose of this test is to reproduce JIRA DERBY-662:
40
41 Sometimes during redo the system would incorrectly remove the file associated
42 with a table. The bug required the following conditions to reproduce:
43 1) The OS/filesystem must be case insensitive such that a request to delete
44    a file named C2080.dat would also remove c2080.dat. This is true in
45    windows default file systems, not true in unix/linux filesystems that
46    I am aware of.
47 2) The system must be shutdown not in a clean manner, such that a subsequent
48    access of the database causes a REDO recovery action of a drop table
49    statement. This means that a drop table statement must have happened
50    since the last checkpoint in the log file. Examples of things that cause
51    checkpoints are:
52    o clean shutdown from ij using the "exit" command
53    o clean shutdown of database using the "shutdown=true" url
54    o calling the checkpoint system procedure
55    o generating enough log activity to cause a regularly scheduled checkpoint.
56 3) If the conglomerate number of the above described drop table is TABLE_1,
57    then for a problem to occur there must also exist in the database a table
58    such that it's HEX(TABLE_2) = TABLE_1
59 4) Either TABLE_2 must not be accessed during REDO prior to the REDO operation
60    of the drop of TABLE_1 or there must be enough other table references during
61    the REDO phase to push the caching of of the open of TABLE_2 out of cache.
62
63 If all of the above conditions are met then during REDO the system will
64 incorrectly delete TABLE_2 while trying to redo the drop of TABLE_1.
65 <p>
66 This test reproduces the problem by doing the following:
67 1) create 500 tables, need enough tables to insure that conglomerate number
68    2080 (c820.dat) and 8320 (c2080.dat) exist.
69 2) checkpoint the database so that create does not happen during REDO
70 3) drop table with conglomerate number 2080, mapping to c820.dat. It looks
71    it up in the catalog in case conglomerate number assignment changes for
72    some reason.
73 4) exit the database without a clean shudown, this is the default for test
74    suites which run multiple tests in a single db - no clean shutdown is done.
75    Since we only do a single drop since the last checkpoint, test will cause
76    the drop during the subsequent REDO.
77 5) run next test program dropcrash2, which will cause redo of the drop. At
78    this point the bug will cause file c2080.dat to be incorrectly deleted and
79    thus accesses to conglomerate 8320 will throw container does not exist
80    errors.
81 6) check the consistency of the database which will find the container does
82    not exist error.
83
84 **/

85
86 public class dropcrash extends BaseTest
87 {
88     boolean verbose = false;
89
90     public dropcrash()
91     {
92     }
93     
94     /**
95      * create tables, commit, and cause checkpoint of db.
96      **/

97     public void drop_crash_setup(
98     Connection JavaDoc conn,
99     int num_create)
100         throws SQLException JavaDoc
101     {
102         beginTest(conn, "creating " + num_create + " tables.");
103         String JavaDoc create_stmt_str1 = "create table dropcrash_";
104         String JavaDoc create_stmt_str2 = " (a int)";
105
106         for (int i = 0; i < num_create; i++)
107         {
108             executeQuery(conn, create_stmt_str1 + i + create_stmt_str2, false);
109         }
110         conn.commit();
111
112         // during redo insure that drop is the only thing redone, if there
113
// are other files in the open file cache then bug will not reproduce
114
// because delete on the open file will fail.
115
executeQuery(
116             conn, "CALL SYSCS_UTIL.SYSCS_CHECKPOINT_DATABASE()", false);
117
118         endTest(conn, "creating " + num_create + " tables.");
119     }
120
121     /**
122      * Reproduce JIRA DERBY-662
123      * <p>
124      * Find the conglomerate with number 2080, and drop it. The bug is
125      * that during redo the system, on windows, will incorrectly delete
126      * C2080.dat because it did not do the hex conversion on the conglomerate
127      * number. This will result in conglomerate 8320 not having it's
128      * associate data file c2080.dat.
129      *
130      * @exception StandardException Standard exception policy.
131      **/

132     public void drop_crash_drop_table(Connection JavaDoc conn)
133         throws SQLException JavaDoc
134     {
135         beginTest(conn, "dropping table with conglomerate number 2080.");
136         PreparedStatement JavaDoc ps =
137             conn.prepareStatement(
138                 "select sys.systables.tablename, sys.sysconglomerates.conglomeratenumber from sys.systables, sys.sysconglomerates where sys.systables.tableid = sys.sysconglomerates.tableid and sys.systables.schemaid = sys.sysconglomerates.schemaid and sys.sysconglomerates.conglomeratenumber = ?");
139         ps.setInt(1, 2080);
140         ResultSet JavaDoc rs = ps.executeQuery();
141
142         if (!rs.next())
143         {
144             System.out.println("ERROR, did not find conglomerate to drop");
145         }
146         String JavaDoc drop_name = rs.getString(1);
147
148         // don't print table name out to test output as it could change if
149
// other recovery tests are added, or system catalogs are added.
150
// System.out.println("dropping table:" + drop_name + " with conglomerate number " + rs.getInt(2));
151
executeQuery(conn, "drop table " + drop_name, false);
152         conn.commit();
153
154         // at this point it is important for this test to exit with not a
155
// clean shutdown, so that the next test will force recovery redo
156
// of this drop.
157
endTest(conn, "dropping table with conglomerate number 2080.");
158     }
159
160     public void testList(Connection JavaDoc conn)
161         throws SQLException JavaDoc
162     {
163         // create enough tables to insure congloms 2080 and 8320 exist
164
drop_crash_setup(conn, 500);
165         // drop 2080 and exit program so that drop will be in REDO recovery
166
drop_crash_drop_table(conn);
167     }
168
169     public static void main(String JavaDoc[] argv)
170         throws Throwable JavaDoc
171     {
172         dropcrash test = new dropcrash();
173
174         ij.getPropertyArg(argv);
175         Connection JavaDoc conn = ij.startJBMS();
176         conn.setAutoCommit(false);
177
178         try
179         {
180             test.testList(conn);
181         }
182         catch (SQLException JavaDoc sqle)
183         {
184             org.apache.derby.tools.JDBCDisplayUtil.ShowSQLException(
185                 System.out, sqle);
186             sqle.printStackTrace(System.out);
187         }
188     }
189 }
190
Popular Tags