Search in sources :

Example 1 with CatalogContext

use of org.voltdb.CatalogContext in project voltdb by VoltDB.

the class UpdateCore method executePlanFragment.

@Override
public DependencyPair executePlanFragment(Map<Integer, List<VoltTable>> dependencies, long fragmentId, ParameterSet params, SystemProcedureExecutionContext context) {
    if (fragmentId == SysProcFragmentId.PF_updateCatalogPrecheckAndSync) {
        String[] tablesThatMustBeEmpty = (String[]) params.getParam(0);
        String[] reasonsForEmptyTables = (String[]) params.getParam(1);
        checkForNonEmptyTables(tablesThatMustBeEmpty, reasonsForEmptyTables, context);
        // Send out fragments to do the initial round-trip to synchronize
        // all the cluster sites on the start of catalog update, we'll do
        // the actual work on the *next* round-trip below
        // Don't actually care about the returned table, just need to send something
        // back to the MPI scoreboard
        DependencyPair success = new DependencyPair.TableDependencyPair(DEP_updateCatalogSync, new VoltTable(new ColumnInfo[] { new ColumnInfo("UNUSED", VoltType.BIGINT) }));
        if (!context.isLowestSiteId()) {
            // id on this host.
            if (log.isInfoEnabled()) {
                log.info("Site " + CoreUtils.hsIdToString(m_site.getCorrespondingSiteId()) + " completed data precheck.");
            }
            return success;
        }
        // We know the ZK bytes are okay because the run() method wrote them before sending
        // out fragments
        CatalogAndIds catalogStuff = null;
        try {
            catalogStuff = CatalogUtil.getCatalogFromZK(VoltDB.instance().getHostMessenger().getZK());
            InMemoryJarfile testjar = new InMemoryJarfile(catalogStuff.catalogBytes);
            JarLoader testjarloader = testjar.getLoader();
            for (String classname : testjarloader.getClassNames()) {
                try {
                    m_javaClass.forName(classname, true, testjarloader);
                }// care about here.
                 catch (UnsupportedClassVersionError e) {
                    String msg = "Cannot load classes compiled with a higher version of Java than currently" + " in use. Class " + classname + " was compiled with ";
                    Integer major = 0;
                    try {
                        major = Integer.parseInt(e.getMessage().split("version")[1].trim().split("\\.")[0]);
                    } catch (Exception ex) {
                        log.debug("Unable to parse compile version number from UnsupportedClassVersionError.", ex);
                    }
                    if (m_versionMap.containsKey(major)) {
                        msg = msg.concat(m_versionMap.get(major) + ", current runtime version is " + System.getProperty("java.version") + ".");
                    } else {
                        msg = msg.concat("an incompatable Java version.");
                    }
                    log.error(msg);
                    throw new VoltAbortException(msg);
                } catch (LinkageError | ClassNotFoundException e) {
                    String cause = e.getMessage();
                    if (cause == null && e.getCause() != null) {
                        cause = e.getCause().getMessage();
                    }
                    String msg = "Error loading class: " + classname + " from catalog: " + e.getClass().getCanonicalName() + ", " + cause;
                    log.warn(msg);
                    throw new VoltAbortException(e);
                }
            }
        } catch (Exception e) {
            Throwables.propagate(e);
        }
        if (log.isInfoEnabled()) {
            log.info("Site " + CoreUtils.hsIdToString(m_site.getCorrespondingSiteId()) + " completed data and catalog precheck.");
        }
        return success;
    } else if (fragmentId == SysProcFragmentId.PF_updateCatalogPrecheckAndSyncAggregate) {
        // Don't actually care about the returned table, just need to send something
        // back to the MPI scoreboard
        log.info("Site " + CoreUtils.hsIdToString(m_site.getCorrespondingSiteId()) + " acknowledged data and catalog prechecks.");
        return new DependencyPair.TableDependencyPair(DEP_updateCatalogSyncAggregate, new VoltTable(new ColumnInfo[] { new ColumnInfo("UNUSED", VoltType.BIGINT) }));
    } else if (fragmentId == SysProcFragmentId.PF_updateCatalog) {
        String catalogDiffCommands = (String) params.toArray()[0];
        String commands = Encoder.decodeBase64AndDecompress(catalogDiffCommands);
        int expectedCatalogVersion = (Integer) params.toArray()[1];
        boolean requiresSnapshotIsolation = ((Byte) params.toArray()[2]) != 0;
        boolean requireCatalogDiffCmdsApplyToEE = ((Byte) params.toArray()[3]) != 0;
        boolean hasSchemaChange = ((Byte) params.toArray()[4]) != 0;
        boolean requiresNewExportGeneration = ((Byte) params.toArray()[5]) != 0;
        CatalogAndIds catalogStuff = null;
        try {
            catalogStuff = CatalogUtil.getCatalogFromZK(VoltDB.instance().getHostMessenger().getZK());
        } catch (Exception e) {
            Throwables.propagate(e);
        }
        String replayInfo = m_runner.getTxnState().isForReplay() ? " (FOR REPLAY)" : "";
        // if this is a new catalog, do the work to update
        if (context.getCatalogVersion() == expectedCatalogVersion) {
            // update the global catalog if we get there first
            @SuppressWarnings("deprecation") Pair<CatalogContext, CatalogSpecificPlanner> p = VoltDB.instance().catalogUpdate(commands, catalogStuff.catalogBytes, catalogStuff.getCatalogHash(), expectedCatalogVersion, DeprecatedProcedureAPIAccess.getVoltPrivateRealTransactionId(this), getUniqueId(), catalogStuff.deploymentBytes, catalogStuff.getDeploymentHash(), requireCatalogDiffCmdsApplyToEE, hasSchemaChange, requiresNewExportGeneration);
            // The producer would have been turned off by the code above already.
            if (VoltDB.instance().getReplicationRole() == ReplicationRole.NONE && !VoltDB.instance().getReplicationActive()) {
                context.resetDrAppliedTracker();
            }
            // update the local catalog.  Safe to do this thanks to the check to get into here.
            long uniqueId = m_runner.getUniqueId();
            long spHandle = m_runner.getTxnState().getNotice().getSpHandle();
            context.updateCatalog(commands, p.getFirst(), p.getSecond(), requiresSnapshotIsolation, uniqueId, spHandle, requireCatalogDiffCmdsApplyToEE, requiresNewExportGeneration);
            if (log.isDebugEnabled()) {
                log.debug(String.format("Site %s completed catalog update with catalog hash %s, deployment hash %s%s.", CoreUtils.hsIdToString(m_site.getCorrespondingSiteId()), Encoder.hexEncode(catalogStuff.getCatalogHash()).substring(0, 10), Encoder.hexEncode(catalogStuff.getDeploymentHash()).substring(0, 10), replayInfo));
            }
        } else // if seen before by this code, then check to see if this is a restart
        if (context.getCatalogVersion() == (expectedCatalogVersion + 1) && Arrays.equals(context.getCatalogHash(), catalogStuff.getCatalogHash()) && Arrays.equals(context.getDeploymentHash(), catalogStuff.getDeploymentHash())) {
            log.info(String.format("Site %s will NOT apply an assumed restarted and identical catalog update with catalog hash %s and deployment hash %s.", CoreUtils.hsIdToString(m_site.getCorrespondingSiteId()), Encoder.hexEncode(catalogStuff.getCatalogHash()), Encoder.hexEncode(catalogStuff.getDeploymentHash())));
        } else {
            VoltDB.crashLocalVoltDB("Invalid catalog update.  Expected version: " + expectedCatalogVersion + ", current version: " + context.getCatalogVersion(), false, null);
        }
        VoltTable result = new VoltTable(VoltSystemProcedure.STATUS_SCHEMA);
        result.addRow(VoltSystemProcedure.STATUS_OK);
        return new DependencyPair.TableDependencyPair(DEP_updateCatalog, result);
    } else if (fragmentId == SysProcFragmentId.PF_updateCatalogAggregate) {
        VoltTable result = VoltTableUtil.unionTables(dependencies.get(DEP_updateCatalog));
        return new DependencyPair.TableDependencyPair(DEP_updateCatalogAggregate, result);
    } else {
        VoltDB.crashLocalVoltDB("Received unrecognized plan fragment id " + fragmentId + " in UpdateApplicationCatalog", false, null);
    }
    throw new RuntimeException("Should not reach this code");
}
Also used : ColumnInfo(org.voltdb.VoltTable.ColumnInfo) CatalogSpecificPlanner(org.voltdb.CatalogSpecificPlanner) InMemoryJarfile(org.voltdb.utils.InMemoryJarfile) CatalogAndIds(org.voltdb.utils.CatalogUtil.CatalogAndIds) VoltTable(org.voltdb.VoltTable) SpecifiedException(org.voltdb.exceptions.SpecifiedException) JarLoader(org.voltdb.utils.InMemoryJarfile.JarLoader) CatalogContext(org.voltdb.CatalogContext) DependencyPair(org.voltdb.DependencyPair)

Example 2 with CatalogContext

use of org.voltdb.CatalogContext in project voltdb by VoltDB.

the class UpdateSettings method executePlanFragment.

@Override
public DependencyPair executePlanFragment(Map<Integer, List<VoltTable>> dependencies, long fragmentId, ParameterSet params, SystemProcedureExecutionContext context) {
    if (fragmentId == SysProcFragmentId.PF_updateSettingsBarrier) {
        DependencyPair success = new DependencyPair.TableDependencyPair(DEP_updateSettingsBarrier, new VoltTable(new ColumnInfo[] { new ColumnInfo("UNUSED", VoltType.BIGINT) }));
        if (log.isInfoEnabled()) {
            log.info("Site " + CoreUtils.hsIdToString(m_site.getCorrespondingSiteId()) + " reached settings update barrier.");
        }
        return success;
    } else if (fragmentId == SysProcFragmentId.PF_updateSettingsBarrierAggregate) {
        Object[] paramarr = params.toArray();
        byte[] settingsBytes = (byte[]) paramarr[0];
        int version = ((Integer) paramarr[1]).intValue();
        ZooKeeper zk = getHostMessenger().getZK();
        Stat stat = null;
        try {
            stat = zk.setData(VoltZK.cluster_settings, settingsBytes, version);
        } catch (KeeperException | InterruptedException e) {
            String msg = "Failed to update cluster settings";
            log.error(msg, e);
            throw new SettingsException(msg, e);
        }
        log.info("Saved new cluster settings state");
        return new DependencyPair.TableDependencyPair(DEP_updateSettingsBarrierAggregate, getVersionResponse(stat.getVersion()));
    } else if (fragmentId == SysProcFragmentId.PF_updateSettings) {
        Object[] paramarr = params.toArray();
        byte[] settingsBytes = (byte[]) paramarr[0];
        int version = ((Integer) paramarr[1]).intValue();
        ClusterSettings settings = ClusterSettings.create(settingsBytes);
        Pair<CatalogContext, CatalogSpecificPlanner> ctgdef = getVoltDB().settingsUpdate(settings, version);
        context.updateSettings(ctgdef.getFirst(), ctgdef.getSecond());
        VoltTable result = new VoltTable(VoltSystemProcedure.STATUS_SCHEMA);
        result.addRow(VoltSystemProcedure.STATUS_OK);
        return new DependencyPair.TableDependencyPair(DEP_updateSettings, result);
    } else if (fragmentId == SysProcFragmentId.PF_updateSettingsAggregate) {
        VoltTable result = VoltTableUtil.unionTables(dependencies.get(DEP_updateSettings));
        return new DependencyPair.TableDependencyPair(DEP_updateSettingsAggregate, result);
    } else {
        VoltDB.crashLocalVoltDB("Received unrecognized plan fragment id " + fragmentId + " in UpdateSettings", false, null);
    }
    throw new RuntimeException("Should not reach this code");
}
Also used : ClusterSettings(org.voltdb.settings.ClusterSettings) ColumnInfo(org.voltdb.VoltTable.ColumnInfo) VoltTable(org.voltdb.VoltTable) SettingsException(org.voltdb.settings.SettingsException) CatalogSpecificPlanner(org.voltdb.CatalogSpecificPlanner) ZooKeeper(org.apache.zookeeper_voltpatches.ZooKeeper) Stat(org.apache.zookeeper_voltpatches.data.Stat) CatalogContext(org.voltdb.CatalogContext) DependencyPair(org.voltdb.DependencyPair)

Example 3 with CatalogContext

use of org.voltdb.CatalogContext in project voltdb by VoltDB.

the class SwapTables method run.

public CompletableFuture<ClientResponse> run(String theTable, String otherTable) {
    String sql = "@SwapTables " + theTable + " " + otherTable;
    Object[] userParams = null;
    CatalogContext context = VoltDB.instance().getCatalogContext();
    List<String> sqlStatements = new ArrayList<>(1);
    sqlStatements.add(sql);
    return runNonDDLAdHoc(context, sqlStatements, true, null, ExplainMode.NONE, true, userParams);
}
Also used : ArrayList(java.util.ArrayList) CatalogContext(org.voltdb.CatalogContext)

Example 4 with CatalogContext

use of org.voltdb.CatalogContext in project voltdb by VoltDB.

the class VoltCompiler method upgradeCatalogAsNeeded.

/**
     * Check a loaded catalog. If it needs to be upgraded recompile it and save
     * an upgraded jar file.
     *
     * @param outputJar  in-memory jar file (updated in place here)
     * @return source version upgraded from or null if not upgraded
     * @throws IOException
     */
public String upgradeCatalogAsNeeded(InMemoryJarfile outputJar) throws IOException {
    // getBuildInfoFromJar() performs some validation.
    String[] buildInfoLines = CatalogUtil.getBuildInfoFromJar(outputJar);
    String versionFromCatalog = buildInfoLines[0];
    // Set if an upgrade happens.
    String upgradedFromVersion = null;
    // getConfig() may return null if it's being mocked for a test.
    if (VoltDB.Configuration.m_forceCatalogUpgrade || !versionFromCatalog.equals(VoltDB.instance().getVersionString())) {
        // Patch the buildinfo.
        String versionFromVoltDB = VoltDB.instance().getVersionString();
        buildInfoLines[0] = versionFromVoltDB;
        buildInfoLines[1] = String.format("voltdb-auto-upgrade-to-%s", versionFromVoltDB);
        byte[] buildInfoBytes = StringUtils.join(buildInfoLines, "\n").getBytes();
        outputJar.put(CatalogUtil.CATALOG_BUILDINFO_FILENAME, buildInfoBytes);
        // Gather DDL files for re-compilation
        List<VoltCompilerReader> ddlReaderList = new ArrayList<>();
        Entry<String, byte[]> entry = outputJar.firstEntry();
        while (entry != null) {
            String path = entry.getKey();
            // ddl files instead of using a brute force *.sql glob.
            if (path.toLowerCase().endsWith(".sql")) {
                ddlReaderList.add(new VoltCompilerJarFileReader(outputJar, path));
            }
            entry = outputJar.higherEntry(entry.getKey());
        }
        // Use the in-memory jarfile-provided class loader so that procedure
        // classes can be found and copied to the new file that gets written.
        ClassLoader originalClassLoader = m_classLoader;
        // Compile and save the file to voltdbroot. Assume it's a test environment if there
        // is no catalog context available.
        String jarName = String.format("catalog-%s.jar", versionFromVoltDB);
        String textName = String.format("catalog-%s.out", versionFromVoltDB);
        CatalogContext catalogContext = VoltDB.instance().getCatalogContext();
        final String outputJarPath = (catalogContext != null ? new File(VoltDB.instance().getVoltDBRootPath(), jarName).getPath() : VoltDB.Configuration.getPathToCatalogForTest(jarName));
        // Place the compiler output in a text file in the same folder.
        final String outputTextPath = (catalogContext != null ? new File(VoltDB.instance().getVoltDBRootPath(), textName).getPath() : VoltDB.Configuration.getPathToCatalogForTest(textName));
        try {
            m_classLoader = outputJar.getLoader();
            consoleLog.info(String.format("Version %s catalog will be automatically upgraded to version %s.", versionFromCatalog, versionFromVoltDB));
            // Do the compilation work.
            boolean success = compileInternalToFile(outputJarPath, null, null, ddlReaderList, outputJar);
            // Bomb out if we failed to generate the canonical DDL
            if (success) {
                boolean foundCanonicalDDL = false;
                entry = outputJar.firstEntry();
                while (entry != null) {
                    String path = entry.getKey();
                    if (path.toLowerCase().endsWith(".sql")) {
                        if (!path.toLowerCase().equals(AUTOGEN_DDL_FILE_NAME)) {
                            outputJar.remove(path);
                        } else {
                            foundCanonicalDDL = true;
                        }
                    }
                    entry = outputJar.higherEntry(entry.getKey());
                }
                success = foundCanonicalDDL;
            }
            if (success) {
                // Set up the return string.
                upgradedFromVersion = versionFromCatalog;
            }
            // Summarize the results to a file.
            // Briefly log success or failure and mention the output text file.
            PrintStream outputStream = new PrintStream(outputTextPath);
            try {
                if (success) {
                    summarizeSuccess(outputStream, outputStream, outputJarPath);
                    consoleLog.info(String.format("The catalog was automatically upgraded from " + "version %s to %s and saved to \"%s\". " + "Compiler output is available in \"%s\".", versionFromCatalog, versionFromVoltDB, outputJarPath, outputTextPath));
                } else {
                    summarizeErrors(outputStream, outputStream);
                    outputStream.close();
                    compilerLog.error("Catalog upgrade failed.");
                    compilerLog.info(String.format("Had attempted to perform an automatic version upgrade of a " + "catalog that was compiled by an older %s version of VoltDB, " + "but the automatic upgrade failed. The cluster  will not be " + "able to start until the incompatibility is fixed. " + "Try re-compiling the catalog with the newer %s version " + "of the VoltDB compiler. Compiler output from the failed " + "upgrade is available in \"%s\".", versionFromCatalog, versionFromVoltDB, outputTextPath));
                    throw new IOException(String.format("Catalog upgrade failed. You will need to recompile using voltdb compile."));
                }
            } finally {
                outputStream.close();
            }
        } catch (IOException ioe) {
            // Do nothing because this could come from the normal failure path
            throw ioe;
        } catch (Exception e) {
            compilerLog.error("Catalog upgrade failed with error:");
            compilerLog.error(e.getMessage());
            compilerLog.info(String.format("Had attempted to perform an automatic version upgrade of a " + "catalog that was compiled by an older %s version of VoltDB, " + "but the automatic upgrade failed. The cluster  will not be " + "able to start until the incompatibility is fixed. " + "Try re-compiling the catalog with the newer %s version " + "of the VoltDB compiler. Compiler output from the failed " + "upgrade is available in \"%s\".", versionFromCatalog, versionFromVoltDB, outputTextPath));
            throw new IOException(String.format("Catalog upgrade failed. You will need to recompile using voltdb compile."));
        } finally {
            // Restore the original class loader
            m_classLoader = originalClassLoader;
        }
    }
    return upgradedFromVersion;
}
Also used : PrintStream(java.io.PrintStream) ArrayList(java.util.ArrayList) IOException(java.io.IOException) JAXBException(javax.xml.bind.JAXBException) SAXException(org.xml.sax.SAXException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) SAXParseException(org.xml.sax.SAXParseException) JarFile(java.util.jar.JarFile) File(java.io.File) CatalogContext(org.voltdb.CatalogContext)

Example 5 with CatalogContext

use of org.voltdb.CatalogContext in project voltdb by VoltDB.

the class VoltCompiler method generateCatalogReport.

private void generateCatalogReport(String ddlWithBatchSupport) throws IOException {
    VoltDBInterface voltdb = VoltDB.instance();
    // try to get a catalog context
    CatalogContext catalogContext = voltdb != null ? voltdb.getCatalogContext() : null;
    ClusterSettings clusterSettings = catalogContext != null ? catalogContext.getClusterSettings() : null;
    int tableCount = catalogContext != null ? catalogContext.tables.size() : 0;
    Deployment deployment = catalogContext != null ? catalogContext.cluster.getDeployment().get("deployment") : null;
    int hostcount = clusterSettings != null ? clusterSettings.hostcount() : 1;
    int kfactor = deployment != null ? deployment.getKfactor() : 0;
    int sitesPerHost = 8;
    if (voltdb != null && voltdb.getCatalogContext() != null) {
        sitesPerHost = voltdb.getCatalogContext().getNodeSettings().getLocalSitesCount();
    }
    boolean isPro = MiscUtils.isPro();
    long minHeapRqt = RealVoltDB.computeMinimumHeapRqt(isPro, tableCount, sitesPerHost, kfactor);
    m_report = ReportMaker.report(m_catalog, minHeapRqt, isPro, hostcount, sitesPerHost, kfactor, m_warnings, ddlWithBatchSupport);
    m_reportPath = null;
    File file = null;
    // write to working dir when using VoltCompiler directly
    if (standaloneCompiler) {
        file = new File("catalog-report.html");
    } else {
        // if we have a context, write report to voltroot
        if (catalogContext != null) {
            file = new File(VoltDB.instance().getVoltDBRootPath(), "catalog-report.html");
        }
    }
    // if there's a good place to write the report, do so
    if (file != null) {
        FileWriter fw = new FileWriter(file);
        fw.write(m_report);
        fw.close();
        m_reportPath = file.getAbsolutePath();
    }
}
Also used : VoltDBInterface(org.voltdb.VoltDBInterface) ClusterSettings(org.voltdb.settings.ClusterSettings) FileWriter(java.io.FileWriter) Deployment(org.voltdb.catalog.Deployment) JarFile(java.util.jar.JarFile) File(java.io.File) CatalogContext(org.voltdb.CatalogContext)

Aggregations

CatalogContext (org.voltdb.CatalogContext)13 File (java.io.File)5 VoltTable (org.voltdb.VoltTable)5 Catalog (org.voltdb.catalog.Catalog)5 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 HostMessenger (org.voltcore.messaging.HostMessenger)3 PlannerTool (org.voltdb.compiler.PlannerTool)3 DbSettings (org.voltdb.settings.DbSettings)3 InMemoryJarfile (org.voltdb.utils.InMemoryJarfile)3 CompletableFuture (java.util.concurrent.CompletableFuture)2 JarFile (java.util.jar.JarFile)2 CatalogSpecificPlanner (org.voltdb.CatalogSpecificPlanner)2 ClientResponseImpl (org.voltdb.ClientResponseImpl)2 DependencyPair (org.voltdb.DependencyPair)2 ColumnInfo (org.voltdb.VoltTable.ColumnInfo)2 Table (org.voltdb.catalog.Table)2 ClientResponse (org.voltdb.client.ClientResponse)2 ClusterSettings (org.voltdb.settings.ClusterSettings)2 FileWriter (java.io.FileWriter)1