All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.voltdb.sysprocs.ValidatePartitioning Maven / Gradle / Ivy

There is a newer version: 10.1.1
Show newest version
/* This file is part of VoltDB.
 * Copyright (C) 2008-2018 VoltDB Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with VoltDB.  If not, see .
 */

package org.voltdb.sysprocs;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.voltcore.logging.VoltLogger;
import org.voltcore.utils.CoreUtils;
import org.voltdb.DependencyPair;
import org.voltdb.ParameterSet;
import org.voltdb.SystemProcedureExecutionContext;
import org.voltdb.TheHashinator;
import org.voltdb.VoltSystemProcedure;
import org.voltdb.VoltTable;
import org.voltdb.VoltTable.ColumnInfo;
import org.voltdb.VoltType;
import org.voltdb.catalog.Table;
import org.voltdb.dtxn.DtxnConstants;
import org.voltdb.utils.CatalogUtil;
import org.voltdb.utils.VoltTableUtil;

import com.google_voltpatches.common.primitives.Longs;

/**
 * A system procedure for validating that the rows at every partition hash correctly when hashed with the
 * hash function stored at the MPI. Optionally you can supply your own hash function which is useful
 * for test where you want to make provide an incorrect hash function to prove
 * that it is actually doing the right thing.
 *
 */
public class ValidatePartitioning extends VoltSystemProcedure {
    private static final VoltLogger HOST_LOG = new VoltLogger("HOST");

    private static final int DEP_validatePartitioning = (int)
            SysProcFragmentId.PF_validatePartitioning | DtxnConstants.MULTIPARTITION_DEPENDENCY;

    private static final int DEP_validatePartitioningResults = (int)
            SysProcFragmentId.PF_validatePartitioningResults;

    private static final int DEP_matchesHashinator = (int)
            SysProcFragmentId.PF_matchesHashinator | DtxnConstants.MULTIPARTITION_DEPENDENCY;

    private static final int DEP_matchesHashinatorResults = (int)
            SysProcFragmentId.PF_matchesHashinatorResults;

    @Override
    public long[] getPlanFragmentIds() {
        return new long[] {
            SysProcFragmentId.PF_validatePartitioningResults,
            SysProcFragmentId.PF_validatePartitioning,
            SysProcFragmentId.PF_matchesHashinatorResults,
            SysProcFragmentId.PF_matchesHashinator
        };
    }

    @Override
    public DependencyPair
    executePlanFragment(Map> dependencies, long fragmentId, ParameterSet params,
                        final SystemProcedureExecutionContext context)
    {
        if (fragmentId == SysProcFragmentId.PF_validatePartitioning) {

            final VoltTable results = constructPartitioningResultsTable();
            List tableIds = new ArrayList();
            List tableNames = new ArrayList();
            for (Table t : CatalogUtil.getSnapshotableTables(context.getDatabase(), false).getFirst()) {
                tableIds.add(t.getRelativeIndex());
                tableNames.add(t.getTypeName());
            }
            long mispartitionedCounts[] = context.getSiteProcedureConnection().validatePartitioning(
                    Longs.toArray(tableIds), (byte[])params.toArray()[0]);

            for (int ii = 0; ii < tableNames.size(); ii++) {
                results.addRow(context.getHostId(), CoreUtils.getSiteIdFromHSId(context.getSiteId()), context.getPartitionId(), tableNames.get(ii), mispartitionedCounts[ii]);
            }
            return new DependencyPair.TableDependencyPair( DEP_validatePartitioning, results);

        } else if (fragmentId == SysProcFragmentId.PF_validatePartitioningResults) {

            assert (dependencies.size() > 0);
            final VoltTable results = VoltTableUtil.unionTables(dependencies.get(DEP_validatePartitioning));
            return new DependencyPair.TableDependencyPair( DEP_validatePartitioningResults, results);

        } else if (fragmentId == SysProcFragmentId.PF_matchesHashinator) {

            final VoltTable matchesHashinator = constructHashinatorMatchesTable();

            byte [] configBytes = (byte[])params.toArray()[0];
            final long givenConfigurationSignature =
                    TheHashinator.computeConfigurationSignature(configBytes);

            matchesHashinator.addRow(
                    context.getHostId(),
                    CoreUtils.getSiteIdFromHSId(context.getSiteId()),
                    context.getPartitionId(),
                    givenConfigurationSignature == TheHashinator.getConfigurationSignature() ? (byte)1 : (byte)0);

            return new DependencyPair.TableDependencyPair(DEP_matchesHashinator, matchesHashinator);

        } else if (fragmentId == SysProcFragmentId.PF_matchesHashinatorResults) {

            assert (dependencies.size() > 0);
            final VoltTable results = VoltTableUtil.unionTables(dependencies.get(DEP_matchesHashinator));
            return new DependencyPair.TableDependencyPair( DEP_matchesHashinatorResults, results);

        }
        assert (false);
        return null;
    }

    private VoltTable constructPartitioningResultsTable() {
        ColumnInfo[] result_columns = new ColumnInfo[5];
        int ii = 0;
        result_columns[ii++] = new ColumnInfo(CNAME_HOST_ID, CTYPE_ID);
        result_columns[ii++] = new ColumnInfo(CNAME_SITE_ID, CTYPE_ID);
        result_columns[ii++] = new ColumnInfo(CNAME_PARTITION_ID, CTYPE_ID);
        result_columns[ii++] = new ColumnInfo("TABLE", VoltType.STRING);
        result_columns[ii++] = new ColumnInfo("MISPARTITIONED_ROWS", VoltType.BIGINT);
        return new VoltTable(result_columns);
    }

    private VoltTable constructHashinatorMatchesTable() {
        ColumnInfo [] columns = new ColumnInfo[] {
                new ColumnInfo(CNAME_HOST_ID, CTYPE_ID),
                new ColumnInfo(CNAME_SITE_ID, CTYPE_ID),
                new ColumnInfo(CNAME_PARTITION_ID, CTYPE_ID),
                new ColumnInfo("HASHINATOR_MATCHES", VoltType.TINYINT)
        };
        return new VoltTable(columns);
    }

    public VoltTable[] run(SystemProcedureExecutionContext ctx, byte config[]) throws VoltAbortException
    {
        final long startTime = System.currentTimeMillis();
        VoltTable retval[];
        if (config != null) {
            retval = performValidatePartitioningWork(config );
        } else {
            retval = performValidatePartitioningWork(
                    TheHashinator.getCurrentConfig().configBytes);
        }
        final long endTime = System.currentTimeMillis();
        final long duration = endTime -startTime;
        HOST_LOG.info("Validating partitioning took " + duration + " milliseconds");
        return retval;
    }

    private final VoltTable[] performValidatePartitioningWork(byte[] config)
    {
        SynthesizedPlanFragment[] pfs = new SynthesizedPlanFragment[2];

        pfs[0] = new SynthesizedPlanFragment();
        pfs[0].fragmentId = SysProcFragmentId.PF_validatePartitioning;
        pfs[0].outputDepId = DEP_validatePartitioning;
        pfs[0].multipartition = true;
        pfs[0].parameters = ParameterSet.fromArrayNoCopy(config);

        pfs[1] = new SynthesizedPlanFragment();
        pfs[1].fragmentId = SysProcFragmentId.PF_validatePartitioningResults;
        pfs[1].outputDepId = DEP_validatePartitioningResults;
        pfs[1].inputDepIds  = new int[] { DEP_validatePartitioning };
        pfs[1].multipartition = false;
        pfs[1].parameters = ParameterSet.emptyParameterSet();

        ArrayList results = new ArrayList();
        for (VoltTable t: executeSysProcPlanFragments(pfs, DEP_validatePartitioningResults)) {
            results.add(t);
        }

        pfs[0] = new SynthesizedPlanFragment();
        pfs[0].fragmentId = SysProcFragmentId.PF_matchesHashinator;
        pfs[0].outputDepId = DEP_matchesHashinator;
        pfs[0].multipartition = true;
        pfs[0].parameters = ParameterSet.fromArrayNoCopy(config);

        pfs[1] = new SynthesizedPlanFragment();
        pfs[1].fragmentId = SysProcFragmentId.PF_matchesHashinatorResults;
        pfs[1].outputDepId = DEP_matchesHashinatorResults;
        pfs[1].inputDepIds  = new int[] { DEP_matchesHashinator };
        pfs[1].multipartition = false;
        pfs[1].parameters = ParameterSet.emptyParameterSet();

        for (VoltTable t: executeSysProcPlanFragments(pfs, DEP_matchesHashinatorResults)) {
            results.add(t);
        }

        return results.toArray(new VoltTable[0]);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy