1 21 22 package org.apache.derbyTesting.unitTests.store; 23 24 import org.apache.derbyTesting.unitTests.harness.T_Generic; 25 import org.apache.derbyTesting.unitTests.harness.T_Fail; 26 27 import org.apache.derbyTesting.unitTests.harness.UnitTest; 28 29 import org.apache.derby.impl.store.raw.log.*; 30 31 import org.apache.derby.iapi.services.context.ContextService; 32 import org.apache.derby.iapi.services.context.ContextManager; 33 import org.apache.derby.iapi.services.daemon.DaemonService; 34 import org.apache.derby.iapi.services.property.PropertyUtil; 35 import org.apache.derby.iapi.services.monitor.Monitor; 36 import org.apache.derby.iapi.services.monitor.ModuleFactory; 37 import org.apache.derby.iapi.services.locks.LockFactory; 38 import org.apache.derby.iapi.services.io.Storable; 39 import org.apache.derby.iapi.services.sanity.SanityManager; 40 import org.apache.derby.iapi.reference.Property; 41 import org.apache.derby.iapi.reference.EngineType; 42 import org.apache.derby.iapi.services.property.PropertyUtil; 43 import org.apache.derby.iapi.services.io.FormatableBitSet; 44 45 import org.apache.derby.iapi.error.StandardException; 46 47 import org.apache.derby.iapi.store.raw.*; 48 49 import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo; 50 51 import java.io.IOException ; 52 import java.io.RandomAccessFile ; 53 import java.io.File ; 54 import java.util.Properties ; 55 56 57 77 78 public class T_RecoverFullLog extends T_Generic { 79 80 private static final String testService = "FullLogTest"; 81 82 static final String REC_001 = "McLaren"; 83 static final String REC_002 = "Ferrari"; 84 static final String REC_003 = "Benetton"; 85 static final String REC_004 = "Prost"; 86 static final String REC_005 = "Tyrell"; 87 static final String REC_006 = "Derby, Natscape, Goatscape, the popular names"; 88 static final String REC_UNDO = "Lotus"; 89 static final String SP1 = "savepoint1"; 90 static final String SP2 = "savepoint2"; 91 92 private RandomAccessFile infofile = null; 93 private static final String infoPath = "extinout/T_RecoverFullLog.info"; 94 95 private boolean fillLog; private boolean recoveryFail; private boolean logSwitchFail; private boolean recover; 100 private String TEST_FILL_LOG = "TestFillLog"; private String TEST_FULL_RECOVER_FAIL = "TestFullRecoveryFail"; private String TEST_LOG_SWITCH_FAIL = "TestLogSwitchFail"; private String TEST_FULL_RECOVER = "TestFullRecover"; 105 private static final String TEST_FULL_LOG_INFO = "TestFullLogInfo"; 106 107 RawStoreFactory factory; 108 LockFactory lf; 109 ContextService contextService; 110 T_Util t_util; 111 112 public T_RecoverFullLog() { 113 super(); 114 } 115 116 119 120 public String getModuleToTestProtocolName() { 121 return RawStoreFactory.MODULE; 122 } 123 124 126 private void getConfig() 127 { 128 String param; 129 130 param = PropertyUtil.getSystemProperty(TEST_FILL_LOG); 131 fillLog = Boolean.valueOf(param).booleanValue(); 132 133 param = PropertyUtil.getSystemProperty(TEST_FULL_RECOVER_FAIL); 134 recoveryFail = Boolean.valueOf(param).booleanValue(); 135 136 param = PropertyUtil.getSystemProperty(TEST_FULL_RECOVER); 137 recover = Boolean.valueOf(param).booleanValue(); 138 139 param = PropertyUtil.getSystemProperty(TEST_LOG_SWITCH_FAIL); 140 logSwitchFail = Boolean.valueOf(param).booleanValue(); 141 } 142 143 148 public void runTests() throws T_Fail { 149 150 getConfig(); 151 int tests = 0; 152 if (fillLog) tests++; 153 if (recoveryFail) tests++; 154 if (recover) tests++; 155 if (logSwitchFail) tests++; 156 157 if (tests != 1) 158 throw T_Fail.testFailMsg("One & only one of the full log recovery test should be run, now " + tests + " set"); 159 160 if (!SanityManager.DEBUG) 161 { 162 REPORT("recoverBadLog cannot be run on an insane server"); 163 return; 164 } 165 166 try { 167 168 contextService = ContextService.getFactory(); 169 170 File ifile = new File (infoPath); 171 172 File ifdir = new File ("extinout"); 174 if(!ifdir.exists()) 175 ifdir.mkdirs(); 176 startParams = T_Util.setEncryptionParam(startParams); 178 179 if (fillLog) { 181 REPORT("_______________________________________________________"); 183 REPORT("\n\t\tcleaning up database for recovering from filled log"); 184 REPORT("_______________________________________________________"); 185 186 if (startParams == null) 188 startParams = new Properties (); 189 190 startParams.put(Property.NO_AUTO_BOOT, Boolean.TRUE.toString()); 191 startParams.put(Property.DELETE_ON_CREATE, Boolean.TRUE.toString()); 193 194 factory = (RawStoreFactory) Monitor.createPersistentService(getModuleToTestProtocolName(), 195 testService, 196 startParams); 197 199 if (ifile.exists()) 201 ifile.delete(); 202 203 204 try 206 { 207 infofile = new RandomAccessFile (ifile, "rw"); 208 } 209 catch (IOException ioe) 210 { 211 System.out.println("Cannot write to temporary file " + 212 infoPath + 213 ". Please make sure it is correct, if not, please set the property " + 214 "TestFullLogInfo=<where temp files should go>"); 215 216 throw T_Fail.exceptionFail(ioe); 217 } 218 219 220 } 221 else 222 { 223 REPORT("_______________________________________________________"); 225 if (recoveryFail) 226 REPORT("\n\t\trecovering database - recovery will fill up log"); 227 else 228 REPORT("\n\t\trecovering database - recovery should succeed"); 229 REPORT("_______________________________________________________"); 230 231 try 232 { 233 infofile = new RandomAccessFile (ifile, "rw"); 235 } 236 catch (IOException ioe) 237 { 238 throw T_Fail.exceptionFail(ioe); 239 } 240 241 if (recoveryFail) 243 { 244 SanityManager.DEBUG_SET(LogToFile.TEST_LOG_FULL); 245 System.setProperty(LogToFile.TEST_RECORD_TO_FILL_LOG, "10"); 246 } 247 248 if (!Monitor.startPersistentService(testService, startParams)) 249 throw T_Fail.testFailMsg("Monitor didn't know how to restart service: " + testService); 250 factory = (RawStoreFactory) Monitor.findService(getModuleToTestProtocolName(), testService); 251 252 if (recoveryFail) 253 { 254 throw T_Fail.testFailMsg("recovery should have failed but did not - did you run the test in order?"); 255 } 256 } 257 } catch (StandardException mse) { 258 259 if (recoveryFail) { 260 REPORT("_______________________________________________________"); 261 REPORT("\n\tRecovery failed due to log full as requested "); 262 REPORT("\texception was " + mse.toString()); 263 REPORT("_______________________________________________________"); 264 return; 265 266 } 267 throw T_Fail.exceptionFail(mse); 268 } catch (NullPointerException npe) { 269 270 if (recoveryFail) { 271 REPORT("_______________________________________________________"); 272 REPORT("\n\tRecovery failed due to log full as requested "); 273 REPORT("\texception was " + npe.toString()); 274 REPORT("_______________________________________________________"); 275 return; 276 277 } 278 throw T_Fail.exceptionFail(npe); 279 } 280 281 282 if (factory == null) { 283 throw T_Fail.testFailMsg(getModuleToTestProtocolName() + " service not started."); 284 } 285 286 lf = factory.getLockFactory(); 287 if (lf == null) { 288 throw T_Fail.testFailMsg("LockFactory.MODULE not found"); 289 } 290 291 t_util = new T_Util(factory, lf, contextService); 293 294 try 295 { 296 if (fillLog) 297 { 298 testBasic(1); 299 fillUpLog(); 300 } 301 else if (logSwitchFail) 302 { 303 testBasic(2); 304 logSwitchFail1(); 305 testBasic(3); 306 logSwitchFail2(); 307 } 308 else if (!recoveryFail) 309 { 310 checkRecovery(); 311 } 312 } catch (StandardException se) { 313 314 throw T_Fail.exceptionFail(se); 315 } 316 } 317 318 private long find(long inkey) 319 { 320 if (infofile == null) 321 return -1; 322 323 try 324 { 325 infofile.seek(0); 326 long key; 327 328 while(true) 329 { 330 key = infofile.readLong(); 331 if (key == inkey) 332 { 333 long value = infofile.readLong(); 334 return value; 336 } 337 infofile.readLong(); 338 } 339 } 340 catch (IOException ioe) 341 { 342 return -1; 344 } 345 346 } 347 348 private long key(int test, int param) 349 { 350 long i = test; 351 return ((i << 32) + param); 352 } 353 354 private void register(long key, long value) 355 throws T_Fail 356 { 357 try 359 { 360 infofile.seek(infofile.length()); 362 infofile.writeLong(key); 363 infofile.writeLong(value); 364 } 365 catch (IOException ioe) 366 { 367 T_Fail.exceptionFail(ioe); 368 } 369 } 370 371 372 377 protected void testBasic(int testNumber) throws T_Fail, StandardException 378 { 379 int numtrans = 7; 380 int numpages = 7; 381 int i,j; 382 383 T_TWC[] t = new T_TWC[numtrans]; 385 for (i = 0; i < numtrans; i++) 386 t[i] = t_util.t_startTransactionWithContext(); 387 388 long[] cid = new long[numtrans]; 389 ContainerHandle[] c = new ContainerHandle[numtrans]; 390 391 for (i = 0; i < numtrans; i++) 392 { 393 cid[i] = t_util.t_addContainer(t[i], 0); 394 t_util.t_commit(t[i]); 395 c[i] = t_util.t_openContainer(t[i], 0, cid[i], true); 396 } 397 398 Page page[][] = new Page[numtrans][numpages]; 399 long pagenum[][] = new long[numtrans][numpages]; 400 401 for (i = 0; i < numtrans; i++) 402 { 403 for (j = 0; j < numpages; j++) 404 { 405 t[i].switchTransactionContext(); 406 page[i][j] = t_util.t_addPage(c[i]); 407 pagenum[i][j] = page[i][j].getPageNumber(); 408 t[i].resetContext(); 409 } 410 } 411 412 445 446 RecordHandle[][] rh = new RecordHandle[numtrans][numpages]; 448 T_RawStoreRow row1 = new T_RawStoreRow(REC_001); 449 for (i = 0; i < numtrans; i++) 450 for (j = 0; j < numpages; j++) 451 { 452 t[i].switchTransactionContext(); 453 rh[i][j] = t_util.t_insert(page[i][j], row1); 454 t[i].resetContext(); 455 } 456 457 t[0].setSavePoint(SP1, null); 459 T_RawStoreRow row2 = new T_RawStoreRow(REC_002); 461 for (i = 0; i < numtrans; i++) 462 for (j = 0; j < numpages; j++) 463 { 464 t[i].switchTransactionContext(); 465 page[i][j].update(rh[i][j], row2.getRow(), (FormatableBitSet) null); 466 t[i].resetContext(); 467 } 468 469 for (i = 1; i < numtrans; i++) { 471 t[i].setSavePoint(SP1, null); 472 } 473 474 T_RawStoreRow row3 = new T_RawStoreRow(REC_003); 476 for (i = 0; i < numtrans; i++) 477 for (j = 0; j < numpages; j++) 478 page[i][j].update(rh[i][j], row3.getRow(), (FormatableBitSet) null); 479 480 for (i = 0; i < numtrans; i++) 481 t[i].setSavePoint(SP2, null); 483 T_RawStoreRow row4 = new T_RawStoreRow(REC_004); 485 for (i = 0; i < numtrans; i++) 486 { 487 t[i].switchTransactionContext(); 488 489 for (j = 0; j < numpages; j++) 490 page[i][j].update(rh[i][j], row4.getRow(), (FormatableBitSet) null); 491 t[i].resetContext(); 492 } 493 494 495 t[0].switchTransactionContext(); 498 499 for (j = 0; j < numpages; j++) 500 page[0][j].unlatch(); 501 502 t[0].rollbackToSavePoint(SP1, null); 504 505 for (j = 0; j < numpages; j++) 507 page[0][j] = t_util.t_getPage(c[0], pagenum[0][j]); 508 509 t[0].resetContext(); 510 511 for (i = 1; i < numtrans; i++) 513 { 514 t[i].switchTransactionContext(); 515 for (j = 0; j < numpages; j++) 516 t_util.t_checkFetch(page[i][j], rh[i][j], REC_004); 517 t[i].resetContext(); 518 } 519 520 t[0].switchTransactionContext(); 521 for (j = 0; j < numpages; j++) 522 t_util.t_checkFetch(page[0][j], rh[0][j], REC_001); 523 524 t[0].resetContext(); 525 T_RawStoreRow row5 = new T_RawStoreRow(REC_005); 527 for (i = 0; i < numtrans; i++) 528 { 529 t[i].switchTransactionContext(); 530 for (j = 0; j < numpages; j++) 531 page[i][j].update(rh[i][j], row5.getRow(), (FormatableBitSet) null); 532 t[i].resetContext(); 533 } 534 535 for (i = 1; i < numtrans; i++) 537 { 538 t[i].switchTransactionContext(); 539 540 for (j = 0; j < numpages; j++) 541 page[i][j].unlatch(); 542 543 t[i].rollbackToSavePoint(SP2, null); 544 545 for (j = 0; j < numpages; j++) 546 page[i][j] = t_util.t_getPage(c[i],pagenum[i][j]); 547 t[i].resetContext(); 548 } 549 550 for (i = 1; i < numtrans; i++) 552 { 553 t[i].switchTransactionContext(); 554 for (j = 0; j < numpages; j++) 555 t_util.t_checkFetch(page[i][j], rh[i][j], REC_003); 556 t[i].resetContext(); 557 } 558 559 t[0].switchTransactionContext(); 560 for (j = 0; j < numpages; j++) 561 t_util.t_checkFetch(page[0][j], rh[0][j], REC_005); 562 563 t[0].resetContext(); 564 565 566 T_RawStoreRow row6 = new T_RawStoreRow(REC_006); 568 for (i = 0; i < numtrans; i++) 569 { 570 t[i].switchTransactionContext(); 571 for (j = 0; j < numpages; j++) 572 page[i][j].update(rh[i][j], row6.getRow(), (FormatableBitSet) null); t[i].resetContext(); 574 } 575 576 t[0].switchTransactionContext(); 579 for (j = 0; j < numpages; j++) 580 page[0][j].unlatch(); 581 582 583 t[0].rollbackToSavePoint(SP1, null); 584 585 for (j = 0; j < numpages; j++) 587 page[0][j] = t_util.t_getPage(c[0], pagenum[0][j]); 588 589 t[0].resetContext(); 590 for (i = 1; i < numtrans; i++) 592 { 593 t[i].switchTransactionContext(); 594 595 for (j = 0; j < numpages; j++) 596 { 597 t_util.t_checkFetch(page[i][j], rh[i][j], REC_006); 598 t_util.t_checkRecordCount(page[i][j], 1, 1); 599 } 600 t[i].resetContext(); 601 } 602 603 t[0].switchTransactionContext(); 604 for (j = 0; j < numpages; j++) 605 { 606 t_util.t_checkFetch(page[0][j], rh[0][j], REC_001); 607 t_util.t_checkRecordCount(page[0][j], 1, 1); 608 } 609 t[0].resetContext(); 610 611 for (i = 0; i < numtrans; i++) 614 { 615 t[i].switchTransactionContext(); 616 for (j = 0; j < numpages; j++) 617 page[i][j].unlatch(); 618 t[i].resetContext(); 619 } 620 621 t_util.t_abort(t[1]); 623 t_util.t_commit(t[2]); 624 t_util.t_commit(t[4]); 626 627 c[1] = t_util.t_openContainer(t[1], 0, cid[1], false); 630 c[2] = t_util.t_openContainer(t[2], 0, cid[2], false); 631 c[4] = t_util.t_openContainer(t[4], 0, cid[4], false); 632 633 for (j = 0; j < numpages; j++) 635 { 636 t[0].switchTransactionContext(); 637 t_util.t_checkFetch(c[0], rh[0][j], REC_001); 638 t[0].resetContext(); 639 640 t[1].switchTransactionContext(); 643 page[1][j] = t_util.t_getPage(c[1], pagenum[1][j]); 644 t_util.t_checkRecordCount(page[1][j], 1, 0); 645 t_util.t_checkFetchBySlot(page[1][j], Page.FIRST_SLOT_NUMBER, 646 REC_001, true, false); 647 page[1][j].unlatch(); 648 t[1].resetContext(); 649 650 t[2].switchTransactionContext(); 651 t_util.t_checkFetch(c[2], rh[2][j], REC_006); 652 t[2].resetContext(); 653 654 t[3].switchTransactionContext(); 655 t_util.t_checkFetch(c[3], rh[3][j], REC_006); 656 t[3].resetContext(); 657 658 t[4].switchTransactionContext(); 659 t_util.t_checkFetch(c[4], rh[4][j], REC_006); 660 t[4].resetContext(); 661 } 662 663 664 for (i = 0; i < numtrans; i++) 665 { 666 register(key(testNumber, i+10), cid[i]); 667 668 String str = "container " + i + ":" + find(key(testNumber,i+10)) + " pages: "; 669 670 for (j = 0; j < numpages; j++) 671 { 672 str += pagenum[i][j] + " "; 673 register(key(testNumber, (i+1)*1000+j), pagenum[i][j]); 674 } 675 REPORT("\t" + str); 676 } 677 678 register(key(testNumber,1), numtrans); 679 register(key(testNumber,2), numpages); 680 681 } 683 684 protected void fillUpLog() throws T_Fail, StandardException 686 { 687 SanityManager.DEBUG_SET(LogToFile.TEST_LOG_FULL); 688 System.setProperty(LogToFile.TEST_RECORD_TO_FILL_LOG, "1"); 689 690 Transaction t = t_util.t_startTransaction(); 691 try 692 { 693 long cid = t_util.t_addContainer(t, 0); 694 } 695 catch (StandardException se) 696 { 697 REPORT("_______________________________________________________"); 698 REPORT("\n\tlog filled up as requested"); 699 REPORT("_______________________________________________________"); 700 return; 701 } 702 catch (NullPointerException npe) 703 { 704 REPORT("_______________________________________________________"); 707 REPORT("\n\tlog filled up as requested"); 708 REPORT("_______________________________________________________"); 709 return; 710 } 711 712 throw T_Fail.testFailMsg("log should have filled but did not"); 713 } 714 715 protected void logSwitchFail1() throws T_Fail, StandardException 716 { 717 SanityManager.DEBUG_SET(LogToFile.TEST_SWITCH_LOG_FAIL1); 718 719 factory.checkpoint(); 722 SanityManager.DEBUG_CLEAR(LogToFile.TEST_SWITCH_LOG_FAIL1); 723 } 724 725 protected void logSwitchFail2() throws T_Fail, StandardException 726 { 727 SanityManager.DEBUG_SET(LogToFile.TEST_SWITCH_LOG_FAIL2); 728 729 int tries = 10; 730 try 731 { 732 736 742 for (int i = 10; i < 110 + tries; i++) 743 { 744 factory.checkpoint(); 745 testBasic(i); 746 } 747 } 748 catch (StandardException se) { 749 REPORT("_______________________________________________________"); 750 REPORT("\n\tlog switch failed as requested"); 751 REPORT("_______________________________________________________"); 752 753 return; 754 } catch (NullPointerException npe) { 755 REPORT("_______________________________________________________"); 756 REPORT("\n\tlog switch failed as requested"); 757 REPORT("_______________________________________________________"); 758 759 return; 760 } 761 finally { SanityManager.DEBUG_CLEAR(LogToFile.TEST_SWITCH_LOG_FAIL2); } 762 763 throw T_Fail.testFailMsg("log switch should have failed but did not even after " + tries + " tries"); 764 } 765 766 protected void checkRecovery() throws T_Fail, StandardException 767 { 768 770 for(int numTest=1; numTest <= 3; numTest++) 771 { 772 int numtrans = (int)find(key(numTest, 1)); 773 int numpages = (int)find(key(numTest, 2)); 774 775 if (numtrans < 5 || numpages < 1) 776 { 777 REPORT("full log test " + numTest + " not run"); 778 continue; 779 } 780 else 781 { 782 REPORT("Test recovery of test " + numTest); 783 } 784 785 Transaction t = t_util.t_startTransaction(); 786 787 long[] cid = new long[numtrans]; 788 ContainerHandle[] c = new ContainerHandle[numtrans]; 789 790 long[][] pagenum = new long[numtrans][numpages]; 791 Page[][] page = new Page[numtrans][numpages]; 792 793 int i,j; 794 795 for (i = 0; i < numtrans; i++) 796 { 797 798 cid[i] = find(key(numTest, i+10)); 799 c[i] = t_util.t_openContainer(t, 0, cid[i], true); 800 801 for (j = 0; j < numpages; j++) 802 { 803 pagenum[i][j] = find(key(numTest, (i+1)*1000+j)); 804 page[i][j] = t_util.t_getPage(c[i], pagenum[i][j]); 805 } 806 } 807 808 for (j = 0; j < numpages; j++) 820 { 821 t_util.t_checkRecordCount(page[0][j], 1, 0); 822 t_util.t_checkFetchBySlot(page[0][j], Page.FIRST_SLOT_NUMBER, 823 REC_001, true, true); 824 825 t_util.t_checkRecordCount(page[1][j], 1, 0); 826 t_util.t_checkFetchBySlot(page[1][j], Page.FIRST_SLOT_NUMBER, 827 REC_001, true, true); 828 829 t_util.t_checkRecordCount(page[2][j], 1, 1); 830 t_util.t_checkFetchBySlot(page[2][j], Page.FIRST_SLOT_NUMBER, 831 REC_006, false, true); 832 833 t_util.t_checkRecordCount(page[3][j], 1, 0); 834 t_util.t_checkFetchBySlot(page[3][j], Page.FIRST_SLOT_NUMBER, 835 REC_001, true, true); 836 837 t_util.t_checkRecordCount(page[4][j], 1, 1); 838 t_util.t_checkFetchBySlot(page[4][j], Page.FIRST_SLOT_NUMBER, 839 REC_006, false, true); 840 } 841 842 for (i = 0; i < numtrans; i++) 843 { 844 String str = "container " + i + ":" + cid[i] + " pages: "; 845 for (j = 0; j < numpages; j++) 846 str += pagenum[i][j] + " "; 847 REPORT("\t" + str); 848 } 849 t_util.t_commit(t); 850 t.close(); 851 852 } 853 } 854 855 856 857 } 858 859 860 | Popular Tags |