Search in sources :

Example 1 with ClientResponse

use of org.voltdb.client.ClientResponse in project voltdb by VoltDB.

the class InvocationDispatcher method useSnapshotCatalogToRestoreSnapshotSchema.

private final ClientResponseImpl useSnapshotCatalogToRestoreSnapshotSchema(final StoredProcedureInvocation task, final InvocationClientHandler handler, final Connection ccxn, final AuthUser user, OverrideCheck bypass) {
    CatalogContext catalogContext = m_catalogContext.get();
    if (!catalogContext.cluster.getUseddlschema()) {
        return gracefulFailureResponse("Cannot restore catalog from snapshot when schema is set to catalog in the deployment.", task.clientHandle);
    }
    log.info("No schema found. Restoring schema and procedures from snapshot.");
    try {
        JSONObject jsObj = new JSONObject(task.getParams().getParam(0).toString());
        final File catalogFH = getSnapshotCatalogFile(jsObj);
        final byte[] catalog;
        try {
            catalog = MiscUtils.fileToBytes(catalogFH);
        } catch (IOException e) {
            log.warn("Unable to access catalog file " + catalogFH, e);
            return unexpectedFailureResponse("Unable to access catalog file " + catalogFH, task.clientHandle);
        }
        final String dep = new String(catalogContext.getDeploymentBytes(), StandardCharsets.UTF_8);
        final StoredProcedureInvocation catalogUpdateTask = new StoredProcedureInvocation();
        catalogUpdateTask.setProcName("@UpdateApplicationCatalog");
        catalogUpdateTask.setParams(catalog, dep);
        //A connection with positive id will be thrown into live client statistics. The connection does not support stats.
        //Thus make the connection id as a negative constant to skip the stats collection.
        final SimpleClientResponseAdapter alternateAdapter = new SimpleClientResponseAdapter(ClientInterface.RESTORE_SCHEMAS_CID, "Empty database snapshot restore catalog update");
        final InvocationClientHandler alternateHandler = new InvocationClientHandler() {

            @Override
            public boolean isAdmin() {
                return handler.isAdmin();
            }

            @Override
            public long connectionId() {
                return ClientInterface.RESTORE_SCHEMAS_CID;
            }
        };
        final long sourceHandle = task.clientHandle;
        SimpleClientResponseAdapter.SyncCallback restoreCallback = new SimpleClientResponseAdapter.SyncCallback();
        final ListenableFuture<ClientResponse> onRestoreComplete = restoreCallback.getResponseFuture();
        onRestoreComplete.addListener(new Runnable() {

            @Override
            public void run() {
                ClientResponse r;
                try {
                    r = onRestoreComplete.get();
                } catch (ExecutionException | InterruptedException e) {
                    VoltDB.crashLocalVoltDB("Should never happen", true, e);
                    return;
                }
                transmitResponseMessage(r, ccxn, sourceHandle);
            }
        }, CoreUtils.SAMETHREADEXECUTOR);
        task.setClientHandle(alternateAdapter.registerCallback(restoreCallback));
        SimpleClientResponseAdapter.SyncCallback catalogUpdateCallback = new SimpleClientResponseAdapter.SyncCallback();
        final ListenableFuture<ClientResponse> onCatalogUpdateComplete = catalogUpdateCallback.getResponseFuture();
        onCatalogUpdateComplete.addListener(new Runnable() {

            @Override
            public void run() {
                ClientResponse r;
                try {
                    r = onCatalogUpdateComplete.get();
                } catch (ExecutionException | InterruptedException e) {
                    VoltDB.crashLocalVoltDB("Should never happen", true, e);
                    return;
                }
                if (r.getStatus() != ClientResponse.SUCCESS) {
                    transmitResponseMessage(r, ccxn, sourceHandle);
                    log.error("Received error response for updating catalog " + r.getStatusString());
                    return;
                }
                m_catalogContext.set(VoltDB.instance().getCatalogContext());
                dispatch(task, alternateHandler, alternateAdapter, user, bypass, false);
            }
        }, CoreUtils.SAMETHREADEXECUTOR);
        catalogUpdateTask.setClientHandle(alternateAdapter.registerCallback(catalogUpdateCallback));
        VoltDB.instance().getClientInterface().bindAdapter(alternateAdapter, null);
        // dispatch the catalog update
        dispatchNTProcedure(alternateHandler, catalogUpdateTask, user, alternateAdapter, System.nanoTime(), false);
    } catch (JSONException e) {
        return unexpectedFailureResponse("Unable to parse parameters.", task.clientHandle);
    }
    return null;
}
Also used : ClientResponse(org.voltdb.client.ClientResponse) JSONException(org.json_voltpatches.JSONException) IOException(java.io.IOException) JSONObject(org.json_voltpatches.JSONObject) VoltFile(org.voltdb.utils.VoltFile) File(java.io.File)

Example 2 with ClientResponse

use of org.voltdb.client.ClientResponse in project voltdb by VoltDB.

the class InvocationDispatcher method takeShutdownSaveSnapshot.

private final ClientResponseImpl takeShutdownSaveSnapshot(final StoredProcedureInvocation task, final InvocationClientHandler handler, final Connection ccxn, final AuthUser user, OverrideCheck bypass) {
    // shutdown save snapshot is available for Pro edition only
    if (!MiscUtils.isPro()) {
        task.setParams();
        return dispatch(task, handler, ccxn, user, bypass, false);
    }
    Object p0 = task.getParams().getParam(0);
    final long zkTxnId;
    if (p0 instanceof Long) {
        zkTxnId = ((Long) p0).longValue();
    } else if (p0 instanceof String) {
        try {
            zkTxnId = Long.parseLong((String) p0);
        } catch (NumberFormatException e) {
            return gracefulFailureResponse("Incorrect argument type", task.clientHandle);
        }
    } else {
        return gracefulFailureResponse("Incorrect argument type", task.clientHandle);
    }
    VoltDBInterface voltdb = VoltDB.instance();
    if (!voltdb.isPreparingShuttingdown()) {
        log.warn("Ignoring shutdown save snapshot request as VoltDB is not shutting down");
        return unexpectedFailureResponse("Ignoring shutdown save snapshot request as VoltDB is not shutting down", task.clientHandle);
    }
    final ZooKeeper zk = voltdb.getHostMessenger().getZK();
    // network threads are blocked from making zookeeper calls
    Future<Long> fut = voltdb.getSES(true).submit(new Callable<Long>() {

        @Override
        public Long call() {
            try {
                Stat stat = zk.exists(VoltZK.operationMode, false);
                if (stat == null) {
                    VoltDB.crashLocalVoltDB("cluster operation mode zookeeper node does not exist");
                    return Long.MIN_VALUE;
                }
                return stat.getMzxid();
            } catch (KeeperException | InterruptedException e) {
                VoltDB.crashLocalVoltDB("Failed to stat the cluster operation zookeeper node", true, e);
                return Long.MIN_VALUE;
            }
        }
    });
    try {
        if (fut.get().longValue() != zkTxnId) {
            return unexpectedFailureResponse("Internal error: cannot write a startup snapshot because the " + "current system state is not consistent with an orderly shutdown. " + "Please try \"voltadmin shutdown --save\" again.", task.clientHandle);
        }
    } catch (InterruptedException | ExecutionException e1) {
        VoltDB.crashLocalVoltDB("Failed to stat the cluster operation zookeeper node", true, e1);
        return null;
    }
    NodeSettings paths = m_catalogContext.get().getNodeSettings();
    String data;
    try {
        data = new JSONStringer().object().keySymbolValuePair(SnapshotUtil.JSON_TERMINUS, zkTxnId).endObject().toString();
    } catch (JSONException e) {
        VoltDB.crashLocalVoltDB("Failed to create startup snapshot save command", true, e);
        return null;
    }
    log.info("Saving startup snapshot");
    consoleLog.info("Taking snapshot to save database contents");
    final SimpleClientResponseAdapter alternateAdapter = new SimpleClientResponseAdapter(ClientInterface.SHUTDONW_SAVE_CID, "Blocking Startup Snapshot Save");
    final InvocationClientHandler alternateHandler = new InvocationClientHandler() {

        @Override
        public boolean isAdmin() {
            return handler.isAdmin();
        }

        @Override
        public long connectionId() {
            return ClientInterface.SHUTDONW_SAVE_CID;
        }
    };
    final long sourceHandle = task.clientHandle;
    task.setClientHandle(alternateAdapter.registerCallback(SimpleClientResponseAdapter.NULL_CALLBACK));
    SnapshotUtil.SnapshotResponseHandler savCallback = new SnapshotUtil.SnapshotResponseHandler() {

        @Override
        public void handleResponse(ClientResponse r) {
            if (r == null) {
                String msg = "Snapshot save failed. The database is paused and the shutdown has been cancelled";
                transmitResponseMessage(gracefulFailureResponse(msg, sourceHandle), ccxn, sourceHandle);
            }
            if (r.getStatus() != ClientResponse.SUCCESS) {
                String msg = "Snapshot save failed: " + r.getStatusString() + ". The database is paused and the shutdown has been cancelled";
                ClientResponseImpl resp = new ClientResponseImpl(ClientResponse.GRACEFUL_FAILURE, r.getResults(), msg, sourceHandle);
                transmitResponseMessage(resp, ccxn, sourceHandle);
            }
            consoleLog.info("Snapshot taken successfully");
            task.setParams();
            dispatch(task, alternateHandler, alternateAdapter, user, bypass, false);
        }
    };
    // network threads are blocked from making zookeeper calls
    final byte[] guardContent = data.getBytes(StandardCharsets.UTF_8);
    Future<Boolean> guardFuture = voltdb.getSES(true).submit(new Callable<Boolean>() {

        @Override
        public Boolean call() throws Exception {
            try {
                ZKUtil.asyncMkdirs(zk, VoltZK.shutdown_save_guard, guardContent).get();
            } catch (NodeExistsException itIsOk) {
                return false;
            } catch (InterruptedException | KeeperException e) {
                VoltDB.crashLocalVoltDB("Failed to create shutdown save guard zookeeper node", true, e);
                return false;
            }
            return true;
        }
    });
    boolean created;
    try {
        created = guardFuture.get().booleanValue();
    } catch (InterruptedException | ExecutionException e) {
        VoltDB.crashLocalVoltDB("Failed to create shutdown save guard zookeeper node", true, e);
        return null;
    }
    if (!created) {
        return unexpectedFailureResponse("Internal error: detected concurrent invocations of \"voltadmin shutdown --save\"", task.clientHandle);
    }
    voltdb.getClientInterface().bindAdapter(alternateAdapter, null);
    SnapshotUtil.requestSnapshot(sourceHandle, paths.resolve(paths.getSnapshoth()).toPath().toUri().toString(), SnapshotUtil.getShutdownSaveNonce(zkTxnId), true, SnapshotFormat.NATIVE, SnapshotPathType.SNAP_AUTO, data, savCallback, true);
    return null;
}
Also used : ClientResponse(org.voltdb.client.ClientResponse) SnapshotUtil(org.voltdb.sysprocs.saverestore.SnapshotUtil) NodeExistsException(org.apache.zookeeper_voltpatches.KeeperException.NodeExistsException) Stat(org.apache.zookeeper_voltpatches.data.Stat) ExecutionException(java.util.concurrent.ExecutionException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) JSONStringer(org.json_voltpatches.JSONStringer) JSONException(org.json_voltpatches.JSONException) JSONException(org.json_voltpatches.JSONException) NodeExistsException(org.apache.zookeeper_voltpatches.KeeperException.NodeExistsException) KeeperException(org.apache.zookeeper_voltpatches.KeeperException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) NodeSettings(org.voltdb.settings.NodeSettings) ZooKeeper(org.apache.zookeeper_voltpatches.ZooKeeper) JSONObject(org.json_voltpatches.JSONObject)

Example 3 with ClientResponse

use of org.voltdb.client.ClientResponse in project voltdb by VoltDB.

the class HealthMonitor method checkDRRole.

private void checkDRRole() {
    SyncCallback cb = new SyncCallback();
    if (getConnectionHadler().callProcedure(getInternalUser(), false, BatchTimeoutOverrideType.NO_TIMEOUT, cb, "@Statistics", "DRROLE", 0)) {
        try {
            cb.waitForResponse();
        } catch (InterruptedException e) {
            m_logger.error("Interrupted while retrieving cluster for DRROLE STATS", e);
            return;
        }
        ClientResponse r = cb.getResponse();
        if (r.getStatus() != ClientResponse.SUCCESS) {
            // timeout could happen if hostdown
            if (m_logger.isDebugEnabled()) {
                m_logger.debug("Unable to retrieve DRROLE STATS: " + r.getStatusString());
            }
            return;
        }
        VoltTable result = r.getResults()[0];
        while (result.advanceRow()) {
            DrRoleType drRole = DrRoleType.fromValue(result.getString(DRRoleStats.CN_ROLE).toLowerCase());
            DRRoleStats.State state = DRRoleStats.State.valueOf(result.getString(DRRoleStats.CN_STATE));
            byte remoteCluster = (byte) result.getLong(DRRoleStats.CN_REMOTE_CLUSTER_ID);
            if (m_logger.isDebugEnabled()) {
                m_logger.debug("DRROLE stats: Role:" + drRole + " State:" + state + " Remote Cluster ID:" + remoteCluster);
            }
            if (drRole == DrRoleType.NONE) {
                continue;
            }
            if (DRRoleStats.State.STOPPED == state) {
                if (!m_snmpDRTrapSent.getOrDefault(remoteCluster, false)) {
                    m_snmpTrapSender.statistics(FaultFacility.DR, String.format("Database Replication ROLE: %s break with Remote Cluster %d.", drRole, remoteCluster));
                    m_snmpDRTrapSent.put(remoteCluster, true);
                }
            } else {
                // reset
                if (m_snmpDRTrapSent.getOrDefault(remoteCluster, false)) {
                    m_snmpDRTrapSent.put(remoteCluster, false);
                }
            }
        }
    } else {
        m_logger.error("Unable to retrieve DRROLE STATS:: failed to invoke @Statistics DRROLE, 0.");
    }
}
Also used : ClientResponse(org.voltdb.client.ClientResponse) DrRoleType(org.voltdb.compiler.deploymentfile.DrRoleType) SyncCallback(org.voltdb.client.SyncCallback)

Example 4 with ClientResponse

use of org.voltdb.client.ClientResponse in project voltdb by VoltDB.

the class TableHelper method fillTableWithBigintPkey.

/**
     * Load random data into a partitioned table in VoltDB that has a bigint pkey.
     *
     * If the VoltTable indicates which column is its pkey, then it will use it, but otherwise it will
     * assume the first column is the bigint pkey. Note, this works with other integer keys, but
     * your keyspace is pretty small.
     *
     * If mb == 0, then maxRows is used. If maxRows == 0, then mb is used.
     *
     * @param table Table with or without schema metadata.
     * @param mb Target RSS (approximate)
     * @param maxRows Target maximum rows
     * @param client To load with.
     * @param offset Generated pkey values start here.
     * @param jump Generated pkey values increment by this value.
     * @throws Exception
     */
public void fillTableWithBigintPkey(VoltTable table, int mb, long maxRows, final Client client, long offset, long jump) throws Exception {
    // make sure some kind of limit is set
    assert ((maxRows > 0) || (mb > 0));
    assert (maxRows >= 0);
    assert (mb >= 0);
    final int mbTarget = mb > 0 ? mb : Integer.MAX_VALUE;
    if (maxRows == 0) {
        maxRows = Long.MAX_VALUE;
    }
    System.out.printf("Filling table %s with rows starting with pkey id %d (every %d rows) until either RSS=%dmb or rowcount=%d\n", table.m_extraMetadata.name, offset, jump, mbTarget, maxRows);
    // find the primary key, assume first col if not found
    int pkeyColIndex = getBigintPrimaryKeyIndexIfExists(table);
    if (pkeyColIndex == -1) {
        pkeyColIndex = 0;
        assert (table.getColumnType(0).isBackendIntegerType());
    }
    final AtomicLong rss = new AtomicLong(0);
    ProcedureCallback insertCallback = new ProcedureCallback() {

        @Override
        public void clientCallback(ClientResponse clientResponse) throws Exception {
            if (clientResponse.getStatus() != ClientResponse.SUCCESS) {
                System.out.println("Error in loader callback:");
                System.out.println(((ClientResponseImpl) clientResponse).toJSONString());
                assert (false);
            }
        }
    };
    // update the rss value asynchronously
    final AtomicBoolean rssThreadShouldStop = new AtomicBoolean(false);
    Thread rssThread = new Thread() {

        @Override
        public void run() {
            long tempRss = rss.get();
            long rssPrev = tempRss;
            while (!rssThreadShouldStop.get()) {
                tempRss = MiscUtils.getMBRss(client);
                if (tempRss != rssPrev) {
                    rssPrev = tempRss;
                    rss.set(tempRss);
                    System.out.printf("RSS=%dmb\n", tempRss);
                    // bail when done
                    if (tempRss > mbTarget) {
                        return;
                    }
                }
                try {
                    Thread.sleep(2000);
                } catch (Exception e) {
                }
            }
        }
    };
    // load rows until RSS goal is met (status print every 100k)
    long i = offset;
    long rows = 0;
    rssThread.start();
    final String insertProcName = table.m_extraMetadata.name.toUpperCase() + ".insert";
    RandomRowMaker filler = createRandomRowMaker(table, Integer.MAX_VALUE, false, false);
    while (rss.get() < mbTarget) {
        Object[] row = filler.randomRow();
        row[pkeyColIndex] = i;
        client.callProcedure(insertCallback, insertProcName, row);
        rows++;
        if ((rows % 100000) == 0) {
            System.out.printf("Loading 100000 rows. %d inserts sent (%d max id).\n", rows, i);
        }
        // if row limit is set, break if it's hit
        if (rows >= maxRows) {
            break;
        }
        i += jump;
    }
    rssThreadShouldStop.set(true);
    client.drain();
    rssThread.join();
    System.out.printf("Filled table %s with %d rows and now RSS=%dmb\n", table.m_extraMetadata.name, rows, rss.get());
}
Also used : ProcedureCallback(org.voltdb.client.ProcedureCallback) ClientResponse(org.voltdb.client.ClientResponse) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicLong(java.util.concurrent.atomic.AtomicLong)

Example 5 with ClientResponse

use of org.voltdb.client.ClientResponse in project voltdb by VoltDB.

the class CheckReplicaConsistency method checkForCorrectness.

/**
     * Core benchmark code. Connect. Initialize. Run the loop. Cleanup. Print
     * Results.
     *
     * @throws Exception
     *             if anything unexpected happens.
     */
public void checkForCorrectness(int ptnOrRep) throws Exception {
    // compare state of all nodes
    // we're employing "short circuit" read queries to get the data on the node
    // exit with nonzero if there is an error
    String z = config.servers;
    String[] servers = z.split(",");
    String[] tblSuffix_ = new String[] { "Ptn", "Rep" };
    String sPtnOrRep = tblSuffix_[ptnOrRep];
    // used for catalog check
    int nTables = 0;
    System.out.printf("Checking data across nodes, case: %s, servers: %s ...\n", sPtnOrRep, z);
    ClientConfig clientConfig = new ClientConfig(config.user, config.password);
    long[] counters = null;
    long[] crcs = null;
    int crcCount = -1;
    for (int iServer = 0; iServer < servers.length; iServer++) {
        String server = servers[iServer];
        Client client = ClientFactory.createClient(clientConfig);
        try {
            client.createConnection(server);
        } catch (Exception e) {
            System.err.printf("Error connecting to node %d %s\n", iServer, server);
            e.printStackTrace();
            throw new RuntimeException();
        }
        ClientResponse resp = null;
        if (iServer == 0) {
            // get the partition count
            resp = client.callProcedure("@Statistics", "PARTITIONCOUNT", 0);
            if (resp.getStatus() != ClientResponse.SUCCESS) {
                System.err.printf("Get partition count failed %s\n", resp.getStatusString());
                throw new RuntimeException();
            }
            VoltTable[] tpc = resp.getResults();
            nPartitions = 0;
            while (tpc[0].advanceRow()) {
                nPartitions = (int) tpc[0].getLong("PARTITION_COUNT");
            }
            System.out.printf("partition count: %d\n", nPartitions);
            if (nPartitions < 2) {
                System.err.printf("Less than 2 partitions\n", nPartitions);
                throw new RuntimeException();
            }
            counters = new long[nPartitions];
            crcs = new long[nPartitions];
        }
        if (nPartitions == 0) {
            System.err.println("Zero partitions should not happen");
            throw new RuntimeException();
        }
        // check the catalog by comparing the number of tables
        resp = client.callProcedure("@Statistics", "TABLE", 0);
        int nt = resp.getResults()[0].getRowCount();
        System.out.printf("table count: %d\n", nt);
        if (iServer == 0)
            nTables = nt;
        else {
            if (nTables != nt) {
                System.err.printf("TEST FAILED Catalog Table count mismatch %d != %d %s %s\n", nTables, nt, server, servers[0]);
                System.exit(1);
            //throw new RuntimeException();
            } else {
                System.out.printf("Catalog test passed\n");
            }
        }
        for (int pid = 0; pid < nPartitions; pid++) {
            // techniques ie. "short circuit" read.
            try {
                long counter = checkAndReturnCounter(server, client, pid, sPtnOrRep);
                if (iServer == 0)
                    counters[pid] = counter;
                else if (counters[pid] != counter) {
                    System.err.printf("TEST FAILED Node counter datacompare mismatch %d != %d %s %s\n", counter, counters[pid], server, servers[0]);
                    System.exit(1);
                //throw new RuntimeException();
                }
            } catch (Exception e) {
                System.err.printf("Exception received calling checkAndReturnCounter: server: %s pid: %d\n%s\n", server, pid, e.getMessage());
                e.printStackTrace();
                throw new RuntimeException();
            }
            // short circuit read techniques) and compare the crc's.
            try {
                long crc = returnCRC(server, client, pid, sPtnOrRep);
                if (iServer == 0)
                    crcs[pid] = crc;
                else if (crcs[pid] != crc) {
                    System.err.printf("TEST FAILED Node crc datacompare mismatch %d != %d %s %s\n", crc, crcs[pid], server, servers[0]);
                    System.exit(1);
                //throw new RuntimeException();
                }
            } catch (Exception e) {
                System.err.printf("Exception received calling returnCRC: server: %s pid: %d\n%s\n", server, pid, e.getMessage());
                e.printStackTrace();
                throw new RuntimeException();
            }
        }
        client.drain();
        client.close();
    }
    System.out.printf("case: %s All nodes of counter identical\n", sPtnOrRep);
}
Also used : ClientResponse(org.voltdb.client.ClientResponse) ClientConfig(org.voltdb.client.ClientConfig) Client(org.voltdb.client.Client) VoltTable(org.voltdb.VoltTable) ProcCallException(org.voltdb.client.ProcCallException) NoConnectionsException(org.voltdb.client.NoConnectionsException) IOException(java.io.IOException)

Aggregations

ClientResponse (org.voltdb.client.ClientResponse)385 VoltTable (org.voltdb.VoltTable)195 Client (org.voltdb.client.Client)184 ProcCallException (org.voltdb.client.ProcCallException)107 IOException (java.io.IOException)54 NoConnectionsException (org.voltdb.client.NoConnectionsException)35 Test (org.junit.Test)32 ProcedureCallback (org.voltdb.client.ProcedureCallback)32 VoltProjectBuilder (org.voltdb.compiler.VoltProjectBuilder)29 Configuration (org.voltdb.VoltDB.Configuration)28 File (java.io.File)19 Timestamp (java.sql.Timestamp)16 VoltDB (org.voltdb.VoltDB)16 InMemoryJarfile (org.voltdb.utils.InMemoryJarfile)16 VoltCompiler (org.voltdb.compiler.VoltCompiler)15 JSONException (org.json_voltpatches.JSONException)11 BigDecimal (java.math.BigDecimal)10 ExecutionException (java.util.concurrent.ExecutionException)10 ClientResponseImpl (org.voltdb.ClientResponseImpl)10 KeeperException (org.apache.zookeeper_voltpatches.KeeperException)9