1 24 25 package org.objectweb.cjdbc.controller.requestmanager; 26 27 import java.sql.SQLException ; 28 import java.util.ArrayList ; 29 import java.util.Date ; 30 import java.util.Hashtable ; 31 import java.util.LinkedList ; 32 import java.util.Vector ; 33 34 import javax.management.NotCompliantMBeanException ; 35 36 import org.objectweb.cjdbc.common.exceptions.BackupException; 37 import org.objectweb.cjdbc.common.exceptions.NoMoreBackendException; 38 import org.objectweb.cjdbc.common.exceptions.RollbackException; 39 import org.objectweb.cjdbc.common.i18n.Translate; 40 import org.objectweb.cjdbc.common.jmx.JmxConstants; 41 import org.objectweb.cjdbc.common.jmx.mbeans.RequestManagerMBean; 42 import org.objectweb.cjdbc.common.jmx.notifications.CjdbcNotificationList; 43 import org.objectweb.cjdbc.common.log.Trace; 44 import org.objectweb.cjdbc.common.shared.BackendState; 45 import org.objectweb.cjdbc.common.shared.DumpInfo; 46 import org.objectweb.cjdbc.common.sql.AbstractWriteRequest; 47 import org.objectweb.cjdbc.common.sql.AlterRequest; 48 import org.objectweb.cjdbc.common.sql.CreateRequest; 49 import org.objectweb.cjdbc.common.sql.ParsingGranularities; 50 import org.objectweb.cjdbc.common.sql.RequestType; 51 import org.objectweb.cjdbc.common.sql.SelectRequest; 52 import org.objectweb.cjdbc.common.sql.StoredProcedure; 53 import org.objectweb.cjdbc.common.sql.UpdateRequest; 54 import org.objectweb.cjdbc.common.sql.schema.DatabaseSchema; 55 import org.objectweb.cjdbc.common.sql.schema.DatabaseTable; 56 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags; 57 import org.objectweb.cjdbc.common.xml.XmlComponent; 58 import org.objectweb.cjdbc.controller.backend.BackendStateListener; 59 import org.objectweb.cjdbc.controller.backend.DatabaseBackend; 60 import org.objectweb.cjdbc.controller.backup.BackupManager; 61 import org.objectweb.cjdbc.controller.backup.Backuper; 62 import org.objectweb.cjdbc.controller.cache.metadata.MetadataCache; 63 import org.objectweb.cjdbc.controller.cache.parsing.ParsingCache; 64 import org.objectweb.cjdbc.controller.cache.result.AbstractResultCache; 65 import org.objectweb.cjdbc.controller.cache.result.entries.AbstractResultCacheEntry; 66 import org.objectweb.cjdbc.controller.jmx.AbstractStandardMBean; 67 import org.objectweb.cjdbc.controller.jmx.MBeanServerManager; 68 import org.objectweb.cjdbc.controller.loadbalancer.AbstractLoadBalancer; 69 import org.objectweb.cjdbc.controller.loadbalancer.AllBackendsFailedException; 70 import org.objectweb.cjdbc.controller.recoverylog.BackendRecoveryInfo; 71 import org.objectweb.cjdbc.controller.recoverylog.RecoverThread; 72 import org.objectweb.cjdbc.controller.recoverylog.RecoveryLog; 73 import org.objectweb.cjdbc.controller.scheduler.AbstractScheduler; 74 import org.objectweb.cjdbc.controller.virtualdatabase.ControllerResultSet; 75 import org.objectweb.cjdbc.controller.virtualdatabase.VirtualDatabase; 76 77 91 public class RequestManager extends AbstractStandardMBean 92 implements 93 XmlComponent, 94 RequestManagerMBean 95 { 96 97 108 109 protected long beginTimeout; 110 111 112 protected long commitTimeout; 113 114 115 protected long rollbackTimeout; 116 117 118 protected VirtualDatabase vdb; 119 120 121 protected AbstractScheduler scheduler; 122 123 124 protected AbstractResultCache resultCache; 125 126 127 protected AbstractLoadBalancer loadBalancer; 128 129 130 protected RecoveryLog recoveryLog; 131 132 133 protected BackupManager backupManager; 134 135 protected DatabaseSchema dbs; 137 138 139 private boolean schemaIsDirty = false; 140 141 private boolean schemaIsStatic = false; 142 143 private boolean isCaseSensitiveParsing = false; 144 145 protected ParsingCache parsingCache = null; 146 147 private MetadataCache metadataCache = null; 148 149 protected int schedulerParsingranularity = ParsingGranularities.NO_PARSING; 152 153 private int cacheParsingranularity = ParsingGranularities.NO_PARSING; 154 155 private int loadBalancerParsingranularity = ParsingGranularities.NO_PARSING; 156 157 protected int requiredParsingGranularity = ParsingGranularities.NO_PARSING; 158 159 160 protected Hashtable tidLoginTable; 161 162 163 protected Hashtable tidSavepoints; 164 165 protected static Trace logger = null; 166 167 private BackendStateListener backendStateListener; 168 169 173 187 public RequestManager(VirtualDatabase vdb, AbstractScheduler scheduler, 188 AbstractResultCache cache, AbstractLoadBalancer loadBalancer, 189 RecoveryLog recoveryLog, long beginTimeout, long commitTimeout, 190 long rollbackTimeout) throws SQLException , NotCompliantMBeanException 191 { 192 super(RequestManagerMBean.class); 193 this.vdb = vdb; 194 assignAndCheckSchedulerLoadBalancerValidity(scheduler, loadBalancer); 195 this.resultCache = cache; 197 if (resultCache != null) 198 { 199 cacheParsingranularity = cache.getParsingGranularity(); 200 if (cacheParsingranularity > requiredParsingGranularity) 201 requiredParsingGranularity = cacheParsingranularity; 202 } 203 setRecoveryLog(recoveryLog); 204 initRequestManagerVariables(vdb, beginTimeout, commitTimeout, 205 rollbackTimeout); 206 setBackendsLastKnownCheckpointFromRecoveryLog(); 207 logger.info(Translate.get("requestmanager.parsing.granularity", 208 ParsingGranularities.getInformation(requiredParsingGranularity))); 209 210 if (MBeanServerManager.isJmxEnabled()) 211 { 212 try 213 { 214 MBeanServerManager.registerMBean(this, JmxConstants 215 .getRequestManagerObjectName(vdb.getVirtualDatabaseName())); 216 217 } 218 catch (Exception e) 219 { 220 logger.error(Translate.get("jmx.failed.register.mbean.requestmanager")); 221 } 222 } 223 } 224 225 229 private void setBackendsLastKnownCheckpointFromRecoveryLog() 230 { 231 232 if (recoveryLog == null) 233 return; 234 String databaseName = vdb.getVirtualDatabaseName(); 235 ArrayList backends = vdb.getBackends(); 236 int size = backends.size(); 237 DatabaseBackend backend; 238 BackendRecoveryInfo info; 239 for (int i = 0; i < size; i++) 240 { 241 backend = (DatabaseBackend) backends.get(i); 242 info = recoveryLog 243 .getBackendRecoveryInfo(databaseName, backend.getName()); 244 backend.setLastKnownCheckpoint(info.getCheckpoint()); 245 } 246 247 } 248 249 257 private void assignAndCheckSchedulerLoadBalancerValidity( 258 AbstractScheduler scheduler, AbstractLoadBalancer loadBalancer) 259 throws SQLException 260 { 261 if (scheduler == null) 262 throw new SQLException (Translate.get("requestmanager.null.scheduler")); 263 264 if (loadBalancer == null) 265 throw new SQLException (Translate.get("requestmanager.null.loadbalancer")); 266 267 if (scheduler.getRAIDbLevel() != loadBalancer.getRAIDbLevel()) 268 throw new SQLException (Translate.get( 269 "requestmanager.incompatible.raidb.levels", 270 new String []{"" + scheduler.getRAIDbLevel(), 271 "" + loadBalancer.getRAIDbLevel()})); 272 273 setScheduler(scheduler); 275 schedulerParsingranularity = scheduler.getParsingGranularity(); 276 requiredParsingGranularity = schedulerParsingranularity; 277 setLoadBalancer(loadBalancer); 278 loadBalancerParsingranularity = loadBalancer.getParsingGranularity(); 279 if (loadBalancerParsingranularity > requiredParsingGranularity) 280 requiredParsingGranularity = loadBalancerParsingranularity; 281 } 282 283 291 private void initRequestManagerVariables(VirtualDatabase vdb, 292 long beginTimeout, long commitTimeout, long rollbackTimeout) 293 { 294 this.tidLoginTable = new Hashtable (); 295 this.tidSavepoints = new Hashtable (); 296 this.beginTimeout = beginTimeout; 297 this.commitTimeout = commitTimeout; 298 this.rollbackTimeout = rollbackTimeout; 299 this.vdb = vdb; 300 logger = Trace.getLogger("org.objectweb.cjdbc.controller.RequestManager." 301 + vdb.getDatabaseName()); 302 } 303 304 308 316 public ControllerResultSet execReadRequest(SelectRequest request) 317 throws SQLException 318 { 319 if (!request.isAutoCommit()) 321 { long tid = request.getTransactionId(); 324 if (!tidLoginTable.containsKey(new Long (tid))) 325 throw new SQLException (Translate.get("transaction.not.started", tid)); 326 } 327 328 if ((requiredParsingGranularity != ParsingGranularities.NO_PARSING) 334 && (!request.isParsed())) 335 { 336 if (parsingCache == null) 337 request.parse(getDatabaseSchema(), requiredParsingGranularity, 338 isCaseSensitiveParsing); 339 else 340 parsingCache.getParsingFromCache(request); 341 } 342 343 347 if ((schedulerParsingranularity != ParsingGranularities.NO_PARSING) 351 && !request.isParsed()) 352 { 353 if (parsingCache == null) 354 request.parse(dbs, requiredParsingGranularity, isCaseSensitiveParsing); 355 else 356 parsingCache.getParsingFromCacheAndParseIfMissing(request); 357 } 358 359 if (logger.isDebugEnabled()) 360 logger.debug(Translate.get("requestmanager.read.request.schedule", 361 new String []{String.valueOf(request.getId()), 362 request.getSQLShortForm(vdb.getSQLShortFormLength())})); 363 364 scheduler.scheduleReadRequest(request); 366 367 371 ControllerResultSet result = null; 372 try 373 { if (resultCache != null) 375 { 376 if (logger.isDebugEnabled()) 377 logger.debug(Translate.get("requestmanager.read.request.cache.get", 378 new String []{String.valueOf(request.getId()), 379 request.getSQLShortForm(vdb.getSQLShortFormLength())})); 380 381 AbstractResultCacheEntry qce = resultCache.getFromCache(request, true); 382 if (qce != null) 383 { 384 result = qce.getResult(); 385 if (result != null) 386 { if (vdb.getSQLMonitor() != null) 388 vdb.getSQLMonitor().logCacheHit(request); 389 390 scheduler.readCompleted(request); 391 return result; 392 } 393 } 394 } 395 396 400 if (logger.isDebugEnabled()) 401 logger.debug(Translate.get("requestmanager.read.request.balance", 402 new String []{String.valueOf(request.getId()), 403 request.getSQLShortForm(vdb.getSQLShortFormLength())})); 404 405 if ((loadBalancerParsingranularity != ParsingGranularities.NO_PARSING) 410 && !request.isParsed()) 411 { 412 if (parsingCache == null) 413 request 414 .parse(dbs, requiredParsingGranularity, isCaseSensitiveParsing); 415 else 416 parsingCache.getParsingFromCacheAndParseIfMissing(request); 417 } 418 419 result = loadBalancer.execReadRequest(request, metadataCache); 421 422 426 if ((resultCache != null) 428 && (request.getCacheAbility() != RequestType.UNCACHEABLE)) 429 { 430 if (logger.isDebugEnabled()) 431 logger.debug(Translate.get( 432 "requestmanager.read.request.cache.update", new String []{ 433 String.valueOf(request.getId()), 434 request.getSQLShortForm(vdb.getSQLShortFormLength())})); 435 436 if (!request.isParsed() 437 && (cacheParsingranularity != ParsingGranularities.NO_PARSING)) 438 { if (parsingCache == null) 441 request.parse(dbs, requiredParsingGranularity, 442 isCaseSensitiveParsing); 443 else 444 parsingCache.getParsingFromCacheAndParseIfMissing(request); 445 } 446 resultCache.addToCache(request, result); 447 } 448 } 449 catch (Exception failed) 450 { 451 if (resultCache != null) 452 resultCache.removeFromPendingQueries(request); 453 scheduler.readCompleted(request); 454 if (failed instanceof NoMoreBackendException) 455 throw (NoMoreBackendException) failed; 456 String msg = Translate.get("requestmanager.request.failed", new String []{ 457 request.getSQLShortForm(vdb.getSQLShortFormLength()), 458 failed.getMessage()}); 459 if (failed instanceof RuntimeException ) 460 logger.warn(msg, failed); 461 else 462 logger.warn(msg); 463 if (failed instanceof SQLException ) 464 throw (SQLException ) failed; 465 466 throw new SQLException (msg); 467 } 468 469 scheduler.readCompleted(request); 471 472 return result; 473 } 474 475 484 public int execWriteRequest(AbstractWriteRequest request) throws SQLException 485 { 486 scheduleExecWriteRequest(request); 487 int execWriteRequestResult = 0; 488 try 489 { 490 execWriteRequestResult = loadBalanceExecWriteRequest(request); 491 } 492 catch (AllBackendsFailedException e) 493 { 494 String msg = Translate 495 .get("requestmanager.write.request.failed.unexpected"); 496 logger.fatal(msg, e); 497 throw new RuntimeException (msg, e); 498 } 499 updateAndNotifyExecWriteRequest(request); 500 return execWriteRequestResult; 501 } 502 503 512 public ControllerResultSet execWriteRequestWithKeys( 513 AbstractWriteRequest request) throws SQLException 514 { 515 scheduleExecWriteRequest(request); 516 ControllerResultSet execWriteRequestWithKeysResult = null; 517 try 518 { 519 execWriteRequestWithKeysResult = loadBalanceExecWriteRequestWithKeys(request); 520 } 521 catch (AllBackendsFailedException e) 522 { 523 String msg = Translate 524 .get("requestmanager.write.request.keys.failed.unexpected"); 525 logger.fatal(msg, e); 526 throw new RuntimeException (msg, e); 527 } 528 updateAndNotifyExecWriteRequest(request); 529 return execWriteRequestWithKeysResult; 530 } 531 532 538 public void scheduleExecWriteRequest(AbstractWriteRequest request) 539 throws SQLException 540 { 541 if (!request.isAutoCommit()) 543 { long tid = request.getTransactionId(); 546 if (!tidLoginTable.containsKey(new Long (tid))) 547 throw new SQLException (Translate.get("transaction.not.started", tid)); 548 } 549 550 if ((requiredParsingGranularity != ParsingGranularities.NO_PARSING) 556 && (!request.isParsed())) 557 { 558 if (parsingCache == null) 559 request.parse(getDatabaseSchema(), requiredParsingGranularity, 560 isCaseSensitiveParsing); 561 else 562 parsingCache.getParsingFromCache(request); 563 } 564 565 569 if ((schedulerParsingranularity != ParsingGranularities.NO_PARSING) 573 && !request.isParsed()) 574 { 575 if (parsingCache == null) 576 request.parse(getDatabaseSchema(), requiredParsingGranularity, 577 isCaseSensitiveParsing); 578 else 579 parsingCache.getParsingFromCacheAndParseIfMissing(request); 580 } 581 582 if (logger.isDebugEnabled()) 583 logger.debug(Translate.get("requestmanager.write.request.schedule", 584 new String []{String.valueOf(request.getId()), 585 request.getSQLShortForm(vdb.getSQLShortFormLength())})); 586 587 try 589 { 590 scheduler.scheduleWriteRequest(request); 591 } 592 catch (RollbackException e) 593 { rollback(request.getTransactionId(), true); 595 throw new SQLException (e.getMessage()); 596 } 597 598 try 604 { 605 if ((requiredParsingGranularity != ParsingGranularities.NO_PARSING) 606 && !request.isParsed()) 607 { 608 if (parsingCache == null) 609 request.parse(getDatabaseSchema(), requiredParsingGranularity, 610 isCaseSensitiveParsing); 611 else 612 parsingCache.getParsingFromCacheAndParseIfMissing(request); 613 } 614 } 615 catch (SQLException e) 616 { 617 scheduler.writeCompleted(request); 619 throw e; 620 } 621 } 622 623 633 public ControllerResultSet loadBalanceExecWriteRequestWithKeys( 634 AbstractWriteRequest request) throws AllBackendsFailedException, 635 SQLException 636 { 637 if (logger.isDebugEnabled()) 638 logger.debug(Translate.get("requestmanager.write.request.balance", 639 new String []{String.valueOf(request.getId()), 640 request.getSQLShortForm(vdb.getSQLShortFormLength())})); 641 642 try 643 { return loadBalancer.execWriteRequestWithKeys(request, metadataCache); 645 } 646 catch (Exception failed) 647 { 648 scheduler.writeCompleted(request); 649 String msg = Translate.get("requestmanager.request.failed", new String []{ 650 request.getSQLShortForm(vdb.getSQLShortFormLength()), 651 failed.getMessage()}); 652 if (failed instanceof RuntimeException ) 653 logger.warn(msg, failed); 654 else 655 logger.warn(msg); 656 if (failed instanceof AllBackendsFailedException) 657 throw (AllBackendsFailedException) failed; 658 else 659 throw new SQLException (msg); 660 } 661 } 662 663 673 public int loadBalanceExecWriteRequest(AbstractWriteRequest request) 674 throws AllBackendsFailedException, SQLException 675 { 676 if (logger.isDebugEnabled()) 677 logger.debug(Translate.get("requestmanager.write.request.balance", 678 new String []{String.valueOf(request.getId()), 679 request.getSQLShortForm(vdb.getSQLShortFormLength())})); 680 681 try 682 { if (request.isUpdate() && (resultCache != null)) 684 { if (!resultCache.isUpdateNecessary((UpdateRequest) request)) 687 return 0; 688 } 689 return loadBalancer.execWriteRequest(request); 690 } 691 catch (Exception failed) 692 { 693 scheduler.writeCompleted(request); 694 String msg = Translate.get("requestmanager.request.failed", new String []{ 695 request.getSQLShortForm(vdb.getSQLShortFormLength()), 696 failed.getMessage()}); 697 698 if (failed instanceof RuntimeException ) 700 logger.warn(msg, failed); 701 else 702 logger.warn(msg); 703 704 if (failed instanceof AllBackendsFailedException) 706 throw (AllBackendsFailedException) failed; 707 else if (failed instanceof SQLException ) 708 throw (SQLException ) failed; 709 else 710 throw new SQLException (msg); 711 } 712 } 713 714 722 public void updateAndNotifyExecWriteRequest(AbstractWriteRequest request) 723 throws SQLException 724 { 725 try 726 { if (resultCache != null) 728 { if (logger.isDebugEnabled()) 730 logger.debug(Translate.get( 731 "requestmanager.write.request.cache.update", new String []{ 732 String.valueOf(request.getId()), 733 request.getSQLShortForm(vdb.getSQLShortFormLength())})); 734 735 resultCache.writeNotify(request); 736 } 737 738 if (metadataCache != null) 739 { 740 if (request.isAlter() || request.isDrop()) 741 metadataCache.flushCache(); 744 } 745 746 if (recoveryLog != null) 748 { 749 if (logger.isDebugEnabled()) 750 logger.debug(Translate.get("requestmanager.write.request.log", 751 new String []{String.valueOf(request.getId()), 752 request.getSQLShortForm(vdb.getSQLShortFormLength())})); 753 754 recoveryLog.logRequest(request); 755 } 756 757 if ((request.isDDL()) 759 && (requiredParsingGranularity != ParsingGranularities.NO_PARSING)) 760 { 761 if (request.isCreate()) 762 { CreateRequest createRequest = (CreateRequest) request; 764 if (createRequest.altersDatabaseSchema()) 765 { 766 if (createRequest.getDatabaseTable() != null) 767 { 768 getDatabaseSchema().addTable( 769 ((CreateRequest) request).getDatabaseTable()); 770 if (logger.isDebugEnabled()) 771 logger.debug(Translate.get("requestmanager.schema.add.table", 772 request.getTableName())); 773 } 774 else 775 schemaIsDirty = true; 778 } 779 } 780 else if (request.isDrop()) 781 { if (getDatabaseSchema().removeTable( 783 getDatabaseSchema().getTable(request.getTableName()))) 784 if (logger.isDebugEnabled()) 785 logger.debug(Translate.get("requestmanager.schema.remove.table", 786 request.getTableName())); 787 else 788 schemaIsDirty = true; 790 } 791 else if (request.isAlter() 792 && (requiredParsingGranularity > ParsingGranularities.TABLE)) 793 { AlterRequest req = (AlterRequest) request; 795 DatabaseTable alteredTable = getDatabaseSchema().getTable( 796 req.getTableName()); 797 if ((alteredTable != null) && (req.getColumn() != null)) 798 { 799 if (req.isDrop()) 800 alteredTable.remove(req.getColumn().getName()); 801 else if (req.isAdd()) 802 alteredTable.addColumn(req.getColumn()); 803 else 804 schemaIsDirty = true; 806 } 807 else 808 schemaIsDirty = true; 810 } 811 else 812 schemaIsDirty = true; 814 } 815 } 816 catch (Exception failed) 817 { 818 scheduler.writeCompleted(request); 819 String msg = Translate.get("requestmanager.request.failed", new String []{ 820 request.getSQLShortForm(vdb.getSQLShortFormLength()), 821 failed.getMessage()}); 822 if (failed instanceof RuntimeException ) 823 logger.warn(msg, failed); 824 else 825 logger.warn(msg); 826 throw new SQLException (msg); 827 } 828 finally 829 { 830 scheduler.writeCompleted(request); 832 } 833 } 834 835 844 public ControllerResultSet execReadStoredProcedure(StoredProcedure proc) 845 throws AllBackendsFailedException, SQLException 846 { 847 ControllerResultSet result = null; 848 try 849 { 850 scheduleStoredProcedure(proc); 851 852 if (logger.isDebugEnabled()) 853 logger.debug(Translate.get("requestmanager.read.stored.procedure", 854 new String []{String.valueOf(proc.getId()), 855 proc.getSQLShortForm(vdb.getSQLShortFormLength())})); 856 857 result = loadBalanceReadStoredProcedure(proc); 858 859 flushCacheAndLogStoredProcedure(proc, true); 860 861 scheduler.storedProcedureCompleted(proc); 863 864 return result; 865 } 866 catch (AllBackendsFailedException e) 867 { 868 throw e; 869 } 870 catch (Exception failed) 871 { 872 scheduler.storedProcedureCompleted(proc); 873 String msg = Translate.get("requestmanager.stored.procedure.failed", 874 new String []{proc.getSQLShortForm(vdb.getSQLShortFormLength()), 875 failed.getMessage()}); 876 logger.warn(msg); 877 if (failed instanceof SQLException ) 878 { 879 throw (SQLException ) failed; 880 } 881 throw new SQLException (msg); 882 } 883 } 884 885 894 public int execWriteStoredProcedure(StoredProcedure proc) 895 throws AllBackendsFailedException, SQLException 896 { 897 int result; 898 try 899 { 900 scheduleStoredProcedure(proc); 902 903 if (logger.isDebugEnabled()) 904 logger.debug(Translate.get("requestmanager.write.stored.procedure", 905 new String []{String.valueOf(proc.getId()), 906 proc.getSQLShortForm(vdb.getSQLShortFormLength())})); 907 908 result = loadBalanceWriteStoredProcedure(proc); 909 910 flushCacheAndLogStoredProcedure(proc, false); 911 912 scheduler.storedProcedureCompleted(proc); 914 915 return result; 916 } 917 catch (AllBackendsFailedException e) 918 { 919 throw e; 920 } 921 catch (Exception failed) 922 { 923 scheduler.storedProcedureCompleted(proc); 924 String msg = Translate.get("requestmanager.stored.procedure.failed", 925 new String []{proc.getSQLShortForm(vdb.getSQLShortFormLength()), 926 failed.getMessage()}); 927 logger.warn(msg); 928 throw new SQLException (msg); 929 } 930 } 931 932 941 public void scheduleStoredProcedure(StoredProcedure proc) throws SQLException 942 { 943 if (!proc.isAutoCommit()) 945 { long tid = proc.getTransactionId(); 948 if (!tidLoginTable.containsKey(new Long (tid))) 949 throw new SQLException (Translate.get("transaction.not.started", tid)); 950 } 951 952 956 try 958 { 959 scheduler.scheduleStoredProcedure(proc); 960 } 961 catch (RollbackException e) 962 { rollback(proc.getTransactionId(), true); 964 throw new SQLException (e.getMessage()); 965 } 966 } 967 968 978 public ControllerResultSet loadBalanceReadStoredProcedure(StoredProcedure proc) 979 throws SQLException , AllBackendsFailedException 980 { 981 ControllerResultSet result; 982 986 if ((resultCache != null) && (!proc.isReadOnly())) 991 resultCache.flushCache(); 992 993 997 if (proc.isReadOnly()) 999 result = loadBalancer 1000 .execReadOnlyReadStoredProcedure(proc, metadataCache); 1001 else 1002 result = loadBalancer.execReadStoredProcedure(proc, metadataCache); 1003 return result; 1004 } 1005 1006 1016 public int loadBalanceWriteStoredProcedure(StoredProcedure proc) 1017 throws AllBackendsFailedException, SQLException 1018 { 1019 int result; 1020 1024 if (resultCache != null) 1026 resultCache.flushCache(); 1027 1028 1032 result = loadBalancer.execWriteStoredProcedure(proc); 1034 return result; 1035 } 1036 1037 1044 public void flushCacheAndLogStoredProcedure(StoredProcedure proc, 1045 boolean isRead) 1046 { 1047 schemaIsDirty = true; 1049 1050 1054 if (resultCache != null) 1057 resultCache.flushCache(); 1058 1059 if (metadataCache != null) 1060 metadataCache.flushCache(); 1061 1062 1066 if (recoveryLog != null) 1067 recoveryLog.logRequest(proc, isRead); 1068 } 1069 1070 1074 1087 public long begin(String login) throws SQLException 1088 { 1089 try 1090 { 1091 TransactionMarkerMetaData tm = new TransactionMarkerMetaData(0, 1092 beginTimeout, login); 1093 1094 long tid = scheduler.begin(tm); 1096 tm.setTransactionId(tid); 1097 1098 if (logger.isDebugEnabled()) 1099 logger.debug(Translate.get("transaction.begin", String.valueOf(tid))); 1100 1101 try 1102 { 1103 loadBalancer.begin(tm); 1105 } 1106 catch (SQLException e) 1107 { 1108 throw e; 1109 } 1110 finally 1111 { 1112 scheduler.beginCompleted(tid); 1114 } 1115 1116 tidLoginTable.put(new Long (tid), tm); 1117 return tid; 1118 } 1119 catch (RuntimeException e) 1120 { 1121 logger.fatal(Translate 1122 .get("fatal.runtime.exception.requestmanager.begin"), e); 1123 throw new SQLException (e.getMessage()); 1124 } 1125 } 1126 1127 1139 public void logLazyTransactionBegin(long transactionId) throws SQLException 1140 { 1141 try 1142 { 1143 Long tid = new Long (transactionId); 1144 TransactionMarkerMetaData tm = getTransactionMarker(tid); 1145 1146 if (logger.isDebugEnabled()) 1147 logger.debug(Translate.get("transaction.begin.log", String 1148 .valueOf(transactionId))); 1149 1150 if (recoveryLog != null) 1152 recoveryLog.logBegin(tm); 1153 } 1154 catch (RuntimeException e) 1155 { 1156 logger.fatal(Translate 1157 .get("fatal.runtime.exception.requestmanager.begin.log"), e); 1158 throw new SQLException (e.getMessage()); 1159 } 1160 } 1161 1162 1173 public void abort(long transactionId, boolean logAbort) throws SQLException 1174 { 1175 try 1176 { 1177 Long tid = new Long (transactionId); 1178 TransactionMarkerMetaData tm = getTransactionMarker(tid); 1179 1180 if (logger.isDebugEnabled()) 1181 logger.debug(Translate.get("transaction.abort", String 1182 .valueOf(transactionId))); 1183 1184 try 1185 { 1186 scheduler.rollback(tm); 1190 1191 if (logAbort && (recoveryLog != null)) 1193 { 1194 recoveryLog.logAbort(tm); 1195 } 1196 } 1197 catch (SQLException e) 1198 { 1199 throw e; 1200 } 1201 finally 1202 { 1203 scheduler.rollbackCompleted(transactionId); 1205 1206 loadBalancer.removeHeadFromAndNotifyTotalOrderQueue(); 1210 1211 completeTransaction(tid); 1212 } 1213 } 1214 catch (RuntimeException e) 1215 { 1216 logger.fatal(Translate 1217 .get("fatal.runtime.exception.requestmanager.abort"), e); 1218 throw new SQLException (e.getMessage()); 1219 } 1220 } 1221 1222 1229 public TransactionMarkerMetaData getTransactionMarker(Long tid) 1230 throws SQLException 1231 { 1232 TransactionMarkerMetaData tm = (TransactionMarkerMetaData) tidLoginTable 1233 .get(tid); 1234 1235 if (tm == null) 1236 throw new SQLException (Translate.get("transaction.marker.not.found", "" 1237 + tid)); 1238 1239 tm.setTimeout(commitTimeout); 1240 return tm; 1241 } 1242 1243 1248 public void completeTransaction(Long tid) 1249 { 1250 tidLoginTable.remove(tid); 1251 tidSavepoints.remove(tid); 1252 } 1253 1254 1261 public void commit(long transactionId, boolean logCommit) throws SQLException 1262 { 1263 try 1264 { 1265 Long tid = new Long (transactionId); 1266 TransactionMarkerMetaData tm = getTransactionMarker(tid); 1267 1268 scheduler.commit(tm); 1270 1271 if (logger.isDebugEnabled()) 1272 logger.debug(Translate.get("transaction.commit", String.valueOf(tid))); 1273 1274 try 1275 { 1276 loadBalancer.commit(tm); 1278 1279 if (resultCache != null) 1281 resultCache.commit(tm.getTransactionId()); 1282 1283 if (logCommit && (recoveryLog != null)) 1285 recoveryLog.logCommit(tm); 1286 } 1287 catch (SQLException e) 1288 { 1289 throw e; 1290 } 1291 catch (AllBackendsFailedException e) 1292 { 1293 String msg = "All backends failed to commit transaction " 1294 + transactionId + " (" + e + ")"; 1295 logger.error(msg); 1296 throw new SQLException (msg); 1297 } 1298 finally 1299 { 1300 scheduler.commitCompleted(transactionId); 1302 1303 completeTransaction(tid); 1304 } 1305 } 1306 catch (RuntimeException e) 1307 { 1308 logger.fatal(Translate 1309 .get("fatal.runtime.exception.requestmanager.commit"), e); 1310 throw new SQLException (e.getMessage()); 1311 } 1312 } 1313 1314 1322 public void rollback(long transactionId, boolean logRollback) 1323 throws SQLException 1324 { 1325 try 1326 { 1327 Long tid = new Long (transactionId); 1328 TransactionMarkerMetaData tm = getTransactionMarker(tid); 1329 1330 scheduler.rollback(tm); 1332 1333 if (logger.isDebugEnabled()) 1334 logger.debug(Translate.get("transaction.rollback", String 1335 .valueOf(transactionId))); 1336 1337 try 1338 { 1339 loadBalancer.rollback(tm); 1341 1342 if (this.resultCache != null) 1344 resultCache.rollback(transactionId); 1345 1346 if (logRollback && (recoveryLog != null)) 1348 { 1349 recoveryLog.logRollback(tm); 1350 } 1351 } 1352 catch (SQLException e) 1353 { 1354 throw e; 1355 } 1356 catch (AllBackendsFailedException e) 1357 { 1358 String msg = Translate.get("requestmanager.rollback.failed.all", 1359 new String []{String.valueOf(transactionId), e.getMessage()}); 1360 logger.error(msg); 1361 throw new SQLException (msg); 1362 } 1363 finally 1364 { 1365 scheduler.rollbackCompleted(transactionId); 1367 1368 completeTransaction(tid); 1369 } 1370 } 1371 catch (RuntimeException e) 1372 { 1373 logger.fatal(Translate 1374 .get("fatal.runtime.exception.requestmanager.rollback"), e); 1375 throw new SQLException (e.getMessage()); 1376 } 1377 } 1378 1379 1386 public void rollback(long transactionId, String savepointName) 1387 throws SQLException 1388 { 1389 try 1390 { 1391 Long tid = new Long (transactionId); 1392 TransactionMarkerMetaData tm = getTransactionMarker(tid); 1393 1394 if (!hasSavepoint(tid, savepointName)) 1396 throw new SQLException (Translate.get("transaction.savepoint.not.found", 1397 new String []{savepointName, String.valueOf(transactionId)})); 1398 1399 scheduler.rollback(tm, savepointName); 1401 1402 if (logger.isDebugEnabled()) 1403 logger.debug(Translate.get("transaction.rollbacksavepoint", 1404 new String []{String.valueOf(transactionId), savepointName})); 1405 try 1406 { 1407 loadBalancer.rollback(tm, savepointName); 1409 1410 if (recoveryLog != null) 1412 { 1413 recoveryLog.logRollback(tm, savepointName); 1414 } 1415 } 1416 catch (AllBackendsFailedException e) 1417 { 1418 String msg = Translate.get( 1419 "requestmanager.rollbackavepoint.failed.all", new String []{ 1420 String.valueOf(transactionId), savepointName, e.getMessage()}); 1421 logger.error(msg); 1422 throw new SQLException (msg); 1423 } 1424 finally 1425 { 1426 scheduler.savepointCompleted(transactionId); 1428 1429 removeSavepoints(tid, savepointName); 1431 } 1432 } 1433 catch (RuntimeException e) 1434 { 1435 logger.fatal(Translate 1436 .get("fatal.runtime.exception.requestmanager.rollbacksavepoint"), e); 1437 throw new SQLException (e.getMessage()); 1438 } 1439 } 1440 1441 1448 public int setSavepoint(long transactionId) throws SQLException 1449 { 1450 try 1451 { 1452 Long tid = new Long (transactionId); 1453 TransactionMarkerMetaData tm = getTransactionMarker(tid); 1454 1455 int savepointId = scheduler.setSavepoint(tm); 1457 String savepointName = String.valueOf(savepointId); 1458 1459 if (logger.isDebugEnabled()) 1460 logger.debug(Translate.get("transaction.setsavepoint", new String []{ 1461 savepointName, String.valueOf(transactionId)})); 1462 1463 try 1464 { 1465 loadBalancer.setSavepoint(tm, savepointName); 1467 1468 if (recoveryLog != null) 1470 { 1471 recoveryLog.logSetSavepoint(tm, savepointName); 1472 } 1473 } 1474 catch (AllBackendsFailedException e) 1475 { 1476 String msg = Translate.get("requestmanager.setsavepoint.failed.all", 1477 new String []{savepointName, String.valueOf(transactionId), 1478 e.getMessage()}); 1479 logger.error(msg); 1480 throw new SQLException (msg); 1481 } 1482 finally 1483 { 1484 scheduler.savepointCompleted(transactionId); 1486 } 1487 1488 addSavepoint(tid, savepointName); 1490 return savepointId; 1491 } 1492 catch (RuntimeException e) 1493 { 1494 logger.fatal(Translate 1495 .get("fatal.runtime.exception.requestmanager.setsavepoint"), e); 1496 throw new SQLException (e.getMessage()); 1497 } 1498 } 1499 1500 1507 public void setSavepoint(long transactionId, String name) throws SQLException 1508 { 1509 try 1510 { 1511 Long tid = new Long (transactionId); 1512 TransactionMarkerMetaData tm = getTransactionMarker(tid); 1513 1514 scheduler.setSavepoint(tm, name); 1516 1517 if (logger.isDebugEnabled()) 1518 logger.debug(Translate.get("transaction.setsavepoint", new String []{ 1519 name, String.valueOf(transactionId)})); 1520 1521 try 1522 { 1523 loadBalancer.setSavepoint(tm, name); 1525 1526 if (recoveryLog != null) 1528 { 1529 recoveryLog.logSetSavepoint(tm, name); 1530 } 1531 } 1532 catch (AllBackendsFailedException e) 1533 { 1534 String msg = Translate.get("requestmanager.setsavepoint.failed.all", 1535 new String []{name, String.valueOf(transactionId), e.getMessage()}); 1536 logger.error(msg); 1537 throw new SQLException (msg); 1538 } 1539 finally 1540 { 1541 scheduler.savepointCompleted(transactionId); 1543 } 1544 1545 addSavepoint(tid, name); 1547 } 1548 catch (RuntimeException e) 1549 { 1550 logger.fatal(Translate 1551 .get("fatal.runtime.exception.requestmanager.setsavepoint"), e); 1552 throw new SQLException (e.getMessage()); 1553 } 1554 } 1555 1556 1563 public void releaseSavepoint(long transactionId, String name) 1564 throws SQLException 1565 { 1566 try 1567 { 1568 Long tid = new Long (transactionId); 1569 TransactionMarkerMetaData tm = getTransactionMarker(tid); 1570 1571 if (!hasSavepoint(tid, name)) 1573 throw new SQLException (Translate.get("transaction.savepoint.not.found", 1574 new String []{name, String.valueOf(transactionId)})); 1575 1576 scheduler.releaseSavepoint(tm, name); 1578 1579 if (logger.isDebugEnabled()) 1580 logger.debug(Translate.get("transaction.releasesavepoint", 1581 new String []{name, String.valueOf(transactionId)})); 1582 1583 try 1584 { 1585 loadBalancer.releaseSavepoint(tm, name); 1587 1588 if (recoveryLog != null) 1590 { 1591 recoveryLog.logReleaseSavepoint(tm, name); 1592 } 1593 } 1594 catch (AllBackendsFailedException e) 1595 { 1596 String msg = Translate.get( 1597 "requestmanager.releasesavepoint.failed.all", new String []{name, 1598 String.valueOf(transactionId), e.getMessage()}); 1599 logger.error(msg); 1600 throw new SQLException (msg); 1601 } 1602 finally 1603 { 1604 scheduler.savepointCompleted(transactionId); 1606 1607 removeSavepoint(tid, name); 1609 } 1610 } 1611 catch (RuntimeException e) 1612 { 1613 logger.fatal(Translate 1614 .get("fatal.runtime.exception.requestmanager.releasesavepoint"), e); 1615 throw new SQLException (e.getMessage()); 1616 } 1617 } 1618 1619 1625 public void addSavepoint(Long tid, String savepointName) 1626 { 1627 LinkedList savepoints = (LinkedList ) tidSavepoints.get(tid); 1628 if (savepoints == null) 1629 { savepoints = new LinkedList (); 1631 tidSavepoints.put(tid, savepoints); 1632 } 1633 1634 savepoints.addLast(savepointName); 1635 } 1636 1637 1643 public void removeSavepoint(Long tid, String savepointName) 1644 { 1645 LinkedList savepoints = (LinkedList ) tidSavepoints.get(tid); 1646 if (savepoints == null) 1647 logger.error("No savepoints found for transaction " + tid); 1648 else 1649 savepoints.remove(savepointName); 1650 } 1651 1652 1659 public void removeSavepoints(Long tid, String savepointName) 1660 { 1661 LinkedList savepoints = (LinkedList ) tidSavepoints.get(tid); 1662 if (savepoints == null) 1663 { 1664 logger.error("No savepoints found for transaction " + tid); 1665 return; 1666 } 1667 1668 int index = savepoints.indexOf(savepointName); 1669 if (index == -1) 1670 logger.error("No savepoint with name " + savepointName + " found " 1671 + "for transaction " + tid); 1672 else 1673 savepoints.subList(index, savepoints.size()).clear(); 1674 } 1675 1676 1683 public boolean hasSavepoint(Long tid, String savepointName) 1684 { 1685 LinkedList savepoints = (LinkedList ) tidSavepoints.get(tid); 1686 if (savepoints == null) 1687 return false; 1688 1689 return savepoints.contains(savepointName); 1690 } 1691 1692 1696 1707 public void enableBackend(DatabaseBackend db) throws SQLException 1708 { 1709 db 1710 .setSchemaIsNeededByVdb(requiredParsingGranularity != ParsingGranularities.NO_PARSING); 1711 loadBalancer.enableBackend(db, true); 1712 logger.info(Translate.get("backend.state.enabled", db.getName())); 1713 } 1714 1715 1732 public RecoverThread enableBackendFromCheckpoint(DatabaseBackend db, 1733 String checkpointName) throws SQLException 1734 { 1735 if (recoveryLog == null) 1737 { 1738 String msg = Translate.get( 1739 "recovery.restore.checkpoint.failed.cause.null", checkpointName); 1740 logger.error(msg); 1741 throw new SQLException (msg); 1742 } 1743 1744 if (db.getStateValue() != BackendState.DISABLED) 1745 throw new SQLException (Translate.get( 1746 "recovery.restore.backend.state.invalid", db.getName())); 1747 1748 db 1749 .setSchemaIsNeededByVdb(requiredParsingGranularity != ParsingGranularities.NO_PARSING); 1750 1751 RecoverThread recoverThread = new RecoverThread(scheduler, recoveryLog, db, 1752 loadBalancer, checkpointName); 1753 1754 recoverThread.start(); 1757 return recoverThread; 1758 } 1759 1760 1770 public void disableBackend(DatabaseBackend db) throws SQLException 1771 { 1772 if (db.isReadEnabled() || db.isWriteEnabled()) 1773 { 1774 loadBalancer.disableBackend(db); 1775 logger.info(Translate.get("backend.state.disabled", db.getName())); 1776 } 1777 else 1778 { 1779 throw new SQLException (Translate.get("backend.already.disabled", db 1780 .getName())); 1781 } 1782 } 1783 1784 1795 public void disableBackendForCheckpoint(DatabaseBackend db, 1796 String checkpointName) throws SQLException 1797 { 1798 if (recoveryLog == null) 1800 { 1801 String msg = Translate.get("recovery.store.checkpoint.failed.cause.null", 1802 checkpointName); 1803 logger.error(msg); 1804 throw new SQLException (msg); 1805 } 1806 1807 logger.info(Translate.get("requestmanager.wait.pending.writes")); 1809 scheduler.suspendWrites(); 1810 1811 recoveryLog.storeCheckpoint(checkpointName); 1813 logger.info(Translate.get("recovery.checkpoint.stored", checkpointName)); 1814 1815 db.setState(BackendState.DISABLING); 1817 logger.info(Translate.get("backend.state.disabling", db.getName())); 1818 1819 logger.info(Translate.get("requestmanager.resume.pending.writes")); 1821 scheduler.resumeWrites(); 1822 1823 db.waitForAllTransactionsToComplete(); 1825 1826 db.setLastKnownCheckpoint(checkpointName); 1828 loadBalancer.disableBackend(db); 1829 logger.info(Translate.get("backend.state.disabled", db.getName())); 1830 } 1831 1832 1842 public void disableBackendsForCheckpoint(ArrayList backendsArrayList, 1843 String checkpointName) throws SQLException 1844 { 1845 if (recoveryLog == null) 1847 { 1848 String msg = Translate.get("recovery.store.checkpoint.failed.cause.null", 1849 checkpointName); 1850 logger.error(msg); 1851 throw new SQLException (msg); 1852 } 1853 1854 logger.info(Translate.get("requestmanager.wait.pending.writes")); 1856 scheduler.suspendWrites(); 1857 1858 recoveryLog.storeCheckpoint(checkpointName); 1860 logger.info(Translate.get("recovery.checkpoint.stored", checkpointName)); 1861 1862 DatabaseBackend db; 1864 ArrayList backendList = (ArrayList ) backendsArrayList.clone(); 1865 for (int i = 0; i < backendList.size(); i++) 1866 { 1867 db = (DatabaseBackend) backendList.get(i); 1868 if (!db.isWriteEnabled()) 1869 backendList.remove(i); 1870 } 1871 1872 int size = backendList.size(); 1874 for (int i = 0; i < size; i++) 1875 { 1876 db = (DatabaseBackend) backendList.get(i); 1877 db.setState(BackendState.DISABLING); 1878 logger.info(Translate.get("backend.state.disabling", db.getName())); 1879 } 1880 1881 logger.info(Translate.get("requestmanager.resume.pending.writes")); 1883 scheduler.resumeWrites(); 1884 1885 for (int i = 0; i < size; i++) 1887 { 1888 db = (DatabaseBackend) backendList.get(i); 1889 db.waitForAllTransactionsToComplete(); 1890 } 1891 1892 for (int i = 0; i < size; i++) 1894 { 1895 db = (DatabaseBackend) backendList.get(i); 1896 db.setLastKnownCheckpoint(checkpointName); 1897 loadBalancer.disableBackend(db); 1898 logger.info(Translate.get("backend.state.disabled", db.getName())); 1899 } 1900 } 1901 1902 1916 public void backupBackend(DatabaseBackend backend, String login, 1917 String password, String dumpName, String backuperName, String path, 1918 ArrayList tables) throws SQLException 1919 { 1920 Backuper backuper = backupManager.getBackuperByName(backuperName); 1921 if (backuper == null) 1922 throw new SQLException ("No backuper named " + backuperName 1923 + " was found."); 1924 1925 boolean enableAfter = false; 1926 String checkpointName = null; 1927 if (backend.isReadEnabled()) 1928 { checkpointName = "cp_for_" + dumpName + "_" 1930 + new Date (System.currentTimeMillis()).toString(); 1931 disableBackendForCheckpoint(backend, checkpointName); 1932 logger.info(Translate.get("backend.state.disabled", backend.getName())); 1933 enableAfter = true; 1934 } 1935 else 1936 { 1937 if (backend.getLastKnownCheckpoint() == null) 1938 { 1939 throw new SQLException (Translate.get( 1940 "controller.backup.no.lastknown.checkpoint", backend.getName())); 1941 } 1942 } 1943 1946 try 1947 { 1948 logger.info(Translate.get("controller.backup.start", backend.getName())); 1949 1950 Vector pending = backend.getPendingRequests(); 1953 if (pending.size() != 0) 1954 { 1955 if (logger.isDebugEnabled()) 1956 { 1957 for (int i = 0; i < pending.size(); i++) 1958 logger.debug("Pending:" + pending.get(i).toString()); 1959 1960 logger.debug("Pending Requests:" 1961 + backend.getPendingRequests().size()); 1962 logger.debug("Read enabled:" + backend.isReadEnabled()); 1963 logger.debug("Write enabled:" + backend.isWriteEnabled()); 1964 } 1965 throw new BackupException(Translate.get("backend.not.ready.for.backup")); 1966 } 1967 1968 backend.setState(BackendState.BACKUPING); 1970 Date dumpDate = backuper.backup(backend, login, password, dumpName, path, 1971 tables); 1972 if (recoveryLog != null) 1973 { 1974 DumpInfo dump = new DumpInfo(dumpName, dumpDate.toString(), path, 1975 backuper.getDumpFormat(), backend.getLastKnownCheckpoint(), backend 1976 .getName(), "*"); 1977 recoveryLog.storeDump(dump); 1978 } 1979 1980 backend.notifyJmx(CjdbcNotificationList.VIRTUALDATABASE_NEW_DUMP_LIST); 1982 1983 backend.setState(BackendState.DISABLED); 1985 } 1986 catch (BackupException be) 1987 { 1988 backend.setState(BackendState.UNKNOWN); 1990 logger.error(Translate.get("controller.backup.failed"), be); 1991 throw new SQLException (be.getMessage()); 1992 } 1993 1994 logger.info(Translate.get("controller.backup.complete", backend.getName())); 1995 1996 if (enableAfter) 1997 { 1998 RecoverThread thread = enableBackendFromCheckpoint(backend, 1999 checkpointName); 2000 try 2001 { 2002 thread.join(); 2003 } 2004 catch (InterruptedException e) 2005 { 2006 logger.error("Recovery thread has been interrupted", e); 2007 } 2008 } 2009 2010 } 2011 2012 2030 public void restoreBackendFromBackupCheckpoint(DatabaseBackend backend, 2031 String login, String password, String dumpName, ArrayList tables) 2032 throws BackupException 2033 { 2034 DumpInfo dumpInfo; 2035 try 2036 { 2037 dumpInfo = recoveryLog.getDumpInfo(dumpName); 2038 } 2039 catch (SQLException e) 2040 { 2041 throw new BackupException( 2042 "Recovery log error access occured while retrieving information for dump " 2043 + dumpName, e); 2044 } 2045 if (dumpInfo == null) 2046 throw new BackupException( 2047 "No information was found in the dump table for dump " + dumpName); 2048 2049 Backuper backuper = backupManager.getBackuperByFormat(dumpInfo 2050 .getDumpFormat()); 2051 if (backuper == null) 2052 throw new BackupException("No backuper was found to handle dump format " 2053 + dumpInfo.getDumpFormat()); 2054 2055 try 2056 { 2057 if (backend.isReadEnabled()) 2060 loadBalancer.disableBackend(backend); 2061 2062 backend.setState(BackendState.RECOVERING); 2063 2064 backuper.restore(backend, login, password, dumpName, dumpInfo 2065 .getDumpPath(), tables); 2066 2067 backend.setLastKnownCheckpoint(dumpInfo.getCheckpointName()); 2069 backend.setState(BackendState.DISABLED); 2070 } 2071 catch (SQLException e1) 2072 { 2073 backend.setState(BackendState.UNKNOWN); 2075 throw new BackupException("Backend cannot be enabled", e1); 2076 } 2077 catch (BackupException be) 2078 { 2079 backend.setState(BackendState.UNKNOWN); 2080 logger.error(Translate.get("controller.backup.recovery.failed"), be); 2081 throw be; 2082 } 2083 finally 2084 { 2085 logger.info(Translate.get("controller.backup.recovery.done", backend 2086 .getName())); 2087 } 2088 } 2089 2090 2096 public void storeBackendsInfo(String databaseName, ArrayList backends) 2097 { 2098 if (recoveryLog == null) 2099 return; 2100 int size = backends.size(); 2101 DatabaseBackend backend; 2102 for (int i = 0; i < size; i++) 2103 { 2104 backend = (DatabaseBackend) backends.get(i); 2105 try 2106 { 2107 recoveryLog.storeBackendRecoveryInfo(databaseName, 2108 new BackendRecoveryInfo(backend.getName(), backend 2109 .getLastKnownCheckpoint(), backend.getStateValue(), 2110 databaseName)); 2111 } 2112 catch (SQLException e) 2113 { 2114 logger.error(Translate.get("recovery.store.checkpoint.failed", 2115 new String []{backend.getName(), e.getMessage()}), e); 2116 } 2117 } 2118 } 2119 2120 2126 public void removeCheckpoint(String checkpointName) throws SQLException 2127 { 2128 recoveryLog.removeCheckpoint(checkpointName); 2129 } 2130 2131 2135 2140 public synchronized DatabaseSchema getDatabaseSchema() 2141 { 2142 try 2143 { 2144 if (schemaIsDirty) 2147 { 2148 dbs = vdb.getDatabaseSchemaFromActiveBackends(); 2149 schemaIsDirty = false; 2150 } 2151 } 2152 catch (SQLException e) 2153 { 2154 logger.error("Unable to refresh schema", e); 2155 } 2156 return dbs; 2157 } 2158 2159 2164 public synchronized void mergeDatabaseSchema(DatabaseSchema backendSchema) 2165 { 2166 try 2167 { 2168 if (dbs == null) 2169 setDatabaseSchema(new DatabaseSchema(backendSchema), false); 2170 else 2171 { 2172 dbs.mergeSchema(backendSchema); 2173 logger.info(Translate 2174 .get("requestmanager.schema.virtualdatabase.merged.new")); 2175 2176 if (schedulerParsingranularity != ParsingGranularities.NO_PARSING) 2177 scheduler.mergeDatabaseSchema(dbs); 2178 2179 if (cacheParsingranularity != ParsingGranularities.NO_PARSING) 2180 resultCache.mergeDatabaseSchema(dbs); 2181 } 2182 } 2183 catch (SQLException e) 2184 { 2185 logger.error(Translate.get("requestmanager.schema.merge.failed", e 2186 .getMessage()), e); 2187 } 2188 } 2189 2190 2197 public synchronized void setDatabaseSchema(DatabaseSchema schema, 2198 boolean isStatic) 2199 { 2200 if (schemaIsStatic) 2201 { 2202 if (isStatic) 2203 { 2204 logger.warn(Translate 2205 .get("requestmanager.schema.replace.static.with.new")); 2206 this.dbs = schema; 2207 } 2208 else 2209 logger.info(Translate.get("requestmanager.schema.ignore.new.dynamic")); 2210 } 2211 else 2212 { 2213 schemaIsStatic = isStatic; 2214 this.dbs = schema; 2215 logger.info(Translate 2216 .get("requestmanager.schema.set.new.virtualdatabase")); 2217 } 2218 2219 if (schedulerParsingranularity != ParsingGranularities.NO_PARSING) 2220 scheduler.setDatabaseSchema(dbs); 2221 2222 if (cacheParsingranularity != ParsingGranularities.NO_PARSING) 2223 resultCache.setDatabaseSchema(dbs); 2224 2225 } 2227 2228 2233 public void setSchemaIsDirty(boolean schemaIsDirty) 2234 { 2235 this.schemaIsDirty = schemaIsDirty; 2236 } 2237 2238 2242 2247 public VirtualDatabase getVirtualDatabase() 2248 { 2249 return vdb; 2250 } 2251 2252 2257 public void setBackupManager(BackupManager currentBackupManager) 2258 { 2259 this.backupManager = currentBackupManager; 2260 } 2261 2262 2267 public BackupManager getBackupManager() 2268 { 2269 return backupManager; 2270 } 2271 2272 2277 public AbstractLoadBalancer getLoadBalancer() 2278 { 2279 return loadBalancer; 2280 } 2281 2282 2287 public void setLoadBalancer(AbstractLoadBalancer loadBalancer) 2288 { 2289 if (this.loadBalancer != null) 2290 throw new RuntimeException ( 2291 "It is not possible to dynamically change a load balancer."); 2292 this.loadBalancer = loadBalancer; 2293 if (loadBalancer == null) 2294 return; 2295 loadBalancerParsingranularity = loadBalancer.getParsingGranularity(); 2296 if (loadBalancerParsingranularity > requiredParsingGranularity) 2297 requiredParsingGranularity = loadBalancerParsingranularity; 2298 2299 if (MBeanServerManager.isJmxEnabled()) 2300 { 2301 try 2302 { 2303 MBeanServerManager.registerMBean(loadBalancer, JmxConstants 2304 .getLoadBalancerObjectName(vdb.getVirtualDatabaseName())); 2305 } 2306 catch (Exception e) 2307 { 2308 logger.error(Translate.get("jmx.failed.register.mbean.loadbalancer")); 2309 } 2310 } 2311 2312 } 2313 2314 2320 public AbstractResultCache getResultCache() 2321 { 2322 return resultCache; 2323 } 2324 2325 2330 public MetadataCache getMetadataCache() 2331 { 2332 return metadataCache; 2333 } 2334 2335 2340 public void setMetadataCache(MetadataCache metadataCache) 2341 { 2342 this.metadataCache = metadataCache; 2343 } 2344 2345 2350 public void setParsingCache(ParsingCache parsingCache) 2351 { 2352 parsingCache.setRequestManager(this); 2353 parsingCache.setGranularity(requiredParsingGranularity); 2354 parsingCache.setCaseSensitiveParsing(isCaseSensitiveParsing); 2355 this.parsingCache = parsingCache; 2356 } 2357 2358 2363 public RecoveryLog getRecoveryLog() 2364 { 2365 return recoveryLog; 2366 } 2367 2368 2373 public void setRecoveryLog(RecoveryLog recoveryLog) 2374 { 2375 if (recoveryLog == null) 2376 return; 2377 this.recoveryLog = recoveryLog; 2378 ArrayList backends = vdb.getBackends(); 2379 int size = backends.size(); 2380 backendStateListener = new BackendStateListener(vdb 2381 .getVirtualDatabaseName(), recoveryLog); 2382 for (int i = 0; i < size; i++) 2383 ((DatabaseBackend) backends.get(i)) 2384 .setStateListener(backendStateListener); 2385 } 2386 2387 2392 public void setResultCache(AbstractResultCache cache) 2393 { 2394 resultCache = cache; 2395 cacheParsingranularity = cache.getParsingGranularity(); 2396 if (cacheParsingranularity > requiredParsingGranularity) 2397 requiredParsingGranularity = cacheParsingranularity; 2398 } 2399 2400 2406 public AbstractScheduler getScheduler() 2407 { 2408 return scheduler; 2409 } 2410 2411 2416 public void setScheduler(AbstractScheduler scheduler) 2417 { 2418 this.scheduler = scheduler; 2419 schedulerParsingranularity = scheduler.getParsingGranularity(); 2420 if (schedulerParsingranularity > requiredParsingGranularity) 2421 requiredParsingGranularity = schedulerParsingranularity; 2422 } 2423 2424 2431 public void setCaseSensitiveParsing(boolean isCaseSensitiveParsing) 2432 { 2433 this.isCaseSensitiveParsing = isCaseSensitiveParsing; 2434 if (parsingCache != null) 2435 parsingCache.setCaseSensitiveParsing(isCaseSensitiveParsing); 2436 } 2437 2438 2442 2447 public String getXml() 2448 { 2449 StringBuffer info = new StringBuffer (); 2450 info.append("<" + DatabasesXmlTags.ELT_RequestManager + " " 2451 + DatabasesXmlTags.ATT_caseSensitiveParsing + "=\"" 2452 + isCaseSensitiveParsing + "\" " + DatabasesXmlTags.ATT_beginTimeout 2453 + "=\"" + beginTimeout / 1000 + "\" " 2454 + DatabasesXmlTags.ATT_commitTimeout + "=\"" + commitTimeout / 1000 2455 + "\" " + DatabasesXmlTags.ATT_rollbackTimeout + "=\"" 2456 + rollbackTimeout / 1000 + "\">"); 2457 if (scheduler != null) 2458 info.append(scheduler.getXml()); 2459 2460 if (metadataCache != null || parsingCache != null || resultCache != null) 2461 { 2462 info.append("<" + DatabasesXmlTags.ELT_RequestCache + ">"); 2463 if (metadataCache != null) 2464 info.append(metadataCache.getXml()); 2465 if (parsingCache != null) 2466 info.append(parsingCache.getXml()); 2467 if (resultCache != null) 2468 info.append(resultCache.getXml()); 2469 info.append("</" + DatabasesXmlTags.ELT_RequestCache + ">"); 2470 } 2471 2472 if (loadBalancer != null) 2473 info.append(loadBalancer.getXml()); 2474 if (recoveryLog != null) 2475 info.append(this.recoveryLog.getXml()); 2476 info.append("</" + DatabasesXmlTags.ELT_RequestManager + ">"); 2477 return info.toString(); 2478 } 2479 2480 2485 public BackendStateListener getBackendStateListener() 2486 { 2487 return backendStateListener; 2488 } 2489 2490 2495 public long getBeginTimeout() 2496 { 2497 return beginTimeout; 2498 } 2499 2500 2505 public void setBeginTimeout(long beginTimeout) 2506 { 2507 this.beginTimeout = beginTimeout; 2508 } 2509 2510 2515 public int getCacheParsingranularity() 2516 { 2517 return cacheParsingranularity; 2518 } 2519 2520 2525 public void setCacheParsingranularity(int cacheParsingranularity) 2526 { 2527 this.cacheParsingranularity = cacheParsingranularity; 2528 } 2529 2530 2535 public long getCommitTimeout() 2536 { 2537 return commitTimeout; 2538 } 2539 2540 2545 public void setCommitTimeout(long commitTimeout) 2546 { 2547 this.commitTimeout = commitTimeout; 2548 } 2549 2550 2555 public int getLoadBalancerParsingranularity() 2556 { 2557 return loadBalancerParsingranularity; 2558 } 2559 2560 2566 public void setLoadBalancerParsingranularity(int loadBalancerParsingranularity) 2567 { 2568 this.loadBalancerParsingranularity = loadBalancerParsingranularity; 2569 } 2570 2571 2576 public int getRequiredParsingGranularity() 2577 { 2578 return requiredParsingGranularity; 2579 } 2580 2581 2586 public void setRequiredParsingGranularity(int requiredGranularity) 2587 { 2588 this.requiredParsingGranularity = requiredGranularity; 2589 } 2590 2591 2596 public long getRollbackTimeout() 2597 { 2598 return rollbackTimeout; 2599 } 2600 2601 2606 public void setRollbackTimeout(long rollbackTimeout) 2607 { 2608 this.rollbackTimeout = rollbackTimeout; 2609 } 2610 2611 2616 public int getSchedulerParsingranularity() 2617 { 2618 return schedulerParsingranularity; 2619 } 2620 2621 2626 public void setSchedulerParsingranularity(int schedulerParsingranularity) 2627 { 2628 this.schedulerParsingranularity = schedulerParsingranularity; 2629 } 2630 2631 2636 public boolean isSchemaIsStatic() 2637 { 2638 return schemaIsStatic; 2639 } 2640 2641 2646 public void setSchemaIsStatic(boolean schemaIsStatic) 2647 { 2648 this.schemaIsStatic = schemaIsStatic; 2649 } 2650 2651 2656 public boolean isCaseSensitiveParsing() 2657 { 2658 return isCaseSensitiveParsing; 2659 } 2660 2661 2664 public String getAssociatedString() 2665 { 2666 return "requestmanager"; 2667 } 2668} 2669 | Popular Tags |