Package org.voltdb.sysprocs

Source Code of org.voltdb.sysprocs.DatabaseDump

package org.voltdb.sysprocs;

import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.voltdb.DependencySet;
import org.voltdb.ParameterSet;
import org.voltdb.ProcInfo;
import org.voltdb.VoltSystemProcedure;
import org.voltdb.VoltTable;
import org.voltdb.VoltType;
import org.voltdb.catalog.Table;

import au.com.bytecode.opencsv.CSVWriter;
import edu.brown.hstore.PartitionExecutor.SystemProcedureExecutionContext;

@ProcInfo(singlePartition = false)
public class DatabaseDump extends VoltSystemProcedure {
   
    private static final Logger LOG = Logger.getLogger(DatabaseDump.class);

    @Override
    public void initImpl() {
        executor.registerPlanFragment(SysProcFragmentId.PF_dumpDistribute, this);
        executor.registerPlanFragment(SysProcFragmentId.PF_dumpAggregate, this);
    }
   
    @Override
    public DependencySet executePlanFragment(Long txn_id, Map<Integer, List<VoltTable>> dependencies, int fragmentId, ParameterSet params, SystemProcedureExecutionContext context) {
        final boolean debug = LOG.isDebugEnabled();
       
        // need to return something ..
        VoltTable[] result = new VoltTable[1];
        result[0] = new VoltTable(new VoltTable.ColumnInfo("TxnId", VoltType.BIGINT));
        result[0].addRow(txn_id);
       
        if (fragmentId == SysProcFragmentId.PF_dumpDistribute) {
            // The first parameter should be the directory
            File directory = new File(params.toArray()[0].toString());
            LOG.debug(String.format("Dumping out database contents for partition %d to '%s'", this.executor.getPartitionId(), directory));
           
            if (directory.exists() == false) {
                LOG.debug("Creating dump directory '" + directory + "'");
                directory.mkdirs();
            }
            assert(directory.isDirectory());
           
            int batch_size = 1000;
           
            // Only write column names if it's the first partition (hack)
            boolean write_header = (this.executor.getPartitionId() == 0);
           
            for (Table catalog_tbl : catalogContext.database.getTables().values()) {
                File csv_file = new File(String.format("%s/%s.%02d.csv", directory, catalog_tbl.getName(), this.executor.getPartitionId()));
                CSVWriter writer = null;
                try {
                    writer = new CSVWriter(new FileWriter(csv_file));
                } catch (Exception ex) {
                    LOG.fatal(String.format("Failed to create CSVWriter for '%s'", csv_file), ex);
                    throw new RuntimeException(ex);
                }
               
                if (write_header) {
                    String cols[] = new String[catalog_tbl.getColumns().size()];
                    for (int i = 0; i < cols.length; i++) {
                        cols[i] = catalog_tbl.getColumns().get(i).getName();
                    } // FOR
                    writer.writeNext(cols);
                }

                int total = 0;
                while (true) {
                    LOG.debug(String.format("%s: offset=%d, limit=%d", catalog_tbl.getName(), total, batch_size));
                    VoltTable vt = this.executor.getExecutionEngine().serializeTable(catalog_tbl.getRelativeIndex());
                    assert(vt != null) : "Failed to get serialized table for " + catalog_tbl;
                    if (vt.getRowCount() == 0) break;
                    total += vt.getRowCount();
                    LOG.debug(String.format("Writing %d / %d tuples to '%s'", vt.getRowCount(), total, csv_file.getName()));
                   
                    // Dump table contents
                    while (vt.advanceRow()) {
                        String row[] = vt.getRowStringArray();
                        assert(row != null);
                        assert(row.length == vt.getColumnCount());
                        writer.writeNext(row);
                    } // WHILE
                } // WHILE
               
                try {
                    writer.close();
                } catch (Exception ex) {
                    throw new RuntimeException(ex);
                }
            } // FOR
            return new DependencySet(new int[] { (int)SysProcFragmentId.PF_dumpDistribute }, result);
           
        } else if (fragmentId == SysProcFragmentId.PF_dumpAggregate) {
            if (debug) LOG.debug("Aggregating results from loading fragments in txn #" + txn_id);
            return new DependencySet(new int[] { (int)SysProcFragmentId.PF_dumpAggregate }, result);
        }
        assert(false) : "Unexpected FragmentId " + fragmentId;
        return null;
    }
   
    /**
     *
     * @param tableName
     * @param table
     * @return
     * @throws VoltAbortException
     */
    public VoltTable[] run(String directory) throws VoltAbortException {
        final boolean debug = LOG.isDebugEnabled();
       
        final ParameterSet params = new ParameterSet(directory);
       
        // Generate a plan fragment for each site using the sub-tables
        final List<SynthesizedPlanFragment> pfs = new ArrayList<SynthesizedPlanFragment>();
        for (int i = 0; i < catalogContext.numberOfPartitions; i++) {
            int partition = i;
            SynthesizedPlanFragment pf = new SynthesizedPlanFragment();
            pf.fragmentId = SysProcFragmentId.PF_dumpDistribute;
            pf.inputDependencyIds = new int[] { };
            pf.outputDependencyIds = new int[] { (int)SysProcFragmentId.PF_dumpDistribute };
            pf.multipartition = false;
            pf.nonExecSites = false;
            pf.destPartitionId = partition;
            pf.parameters = params;
            pf.last_task = true;
            pfs.add(pf);
        } // FOR

        // a final plan fragment to aggregate the results
//        pfs[0] = new SynthesizedPlanFragment();
//        pfs[0].destPartitionId = partitionId;
//        pfs[0].fragmentId = SysProcFragmentId.PF_dumpAggregate;
//        pfs[0].inputDependencyIds = new int[] { (int)SysProcFragmentId.PF_dumpDistribute };
//        pfs[0].outputDependencyIds = new int[] { (int)SysProcFragmentId.PF_dumpAggregate };
//        pfs[0].multipartition = false;
//        pfs[0].nonExecSites = false;
//        pfs[0].parameters = new ParameterSet();

        // send these forth in to the world .. and wait
        if (debug) LOG.debug("Passing " + pfs.size() + " sysproc fragments to executeSysProcPlanFragments()");
        VoltTable[] results = executeSysProcPlanFragments(pfs.toArray(new SynthesizedPlanFragment[0]), (int)SysProcFragmentId.PF_dumpDistribute);
        return results;
    }

}
TOP

Related Classes of org.voltdb.sysprocs.DatabaseDump

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.