Package org.chaidb.db.transaction.recover

Source Code of org.chaidb.db.transaction.recover.NormalTransactionRecoverImpl

/*
* Copyright (C) 2006  http://www.chaidb.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
*/

package org.chaidb.db.transaction.recover;

import org.apache.log4j.Logger;
import org.chaidb.db.exception.ChaiDBException;
import org.chaidb.db.log.LogManager;
import org.chaidb.db.log.LogRecord;
import org.chaidb.db.log.Lsn;
import org.chaidb.db.log.logrecord.TxnFuzzyCkpLogRecord;
import org.chaidb.db.transaction.TransactionManager;


/**
* This class implements normal transaction recovery.
* It extends from abstract class TransactionRecoverImpl.
*
* @version 1.0
*/
public class NormalTransactionRecoverImpl extends TransactionRecoverImpl {

    private static final Logger logger = Logger.getLogger(NormalTransactionRecoverImpl.class);

    /**
     * Constructor.
     *
     * @param txnManager The transaction manager is responsible for managing
     *                   the normal transaction recovery implement.
     */
    public NormalTransactionRecoverImpl(TransactionManager txnManager) {
        super(txnManager);
    }


    /**
     * 1.do undo to smallest_lsn saved in fuzzy checkpoint in V3.1
     * 2.do undo to checkpoint in V3.0
     * V3.1 should be compatible to V3.0
     */
    protected boolean undo() throws ChaiDBException {
        this.status = UNDO_STAGE;
        Lsn cursorLsn = null;
        LogRecord cursorLogRecord = null;
        int countCkp = 0; //checkpoint count number

        //Gets the lastest lsn in lsn.idb file.
        cursorLsn = txnManager.getLogManager().getLastLsnInFlush();
        boolean isEnd = false;
        Lsn smallestLsn = null;
        while (!isEnd) {
            try {
                cursorLogRecord = txnManager.getLogManager().get(cursorLsn);
            } catch (ChaiDBException e) {
                logger.error(e);
                throw e;
            }
            /* according to different log type to do different handling */
            switch (cursorLogRecord.getType()) {
                case LogRecord.LOG_TXN_CHILD:
                    break;
                case LogRecord.LOG_TXN_CHECKPOINT://V3.0 standard checkpoint consistent state
                    countCkp++;
                    if (countCkp == 1) {
                        this.txnManager.setLastCkp(cursorLsn);
                    } else if (countCkp == 2) {
                        isEnd = true;
                    }
                    break;
                case LogRecord.LOG_TXN_FUZZY_CHECKPOINT://V3.1 fuzzy checkpoint
                    countCkp++;
                    if (countCkp == 1) {
                        this.txnManager.setLastCkp(cursorLsn);
                    } else if (countCkp == 2) {
                        TxnFuzzyCkpLogRecord fuzzyCkpLog = (TxnFuzzyCkpLogRecord) cursorLogRecord;
                        /* V3.1, if no active txn while doing fuzzy checkpoint,
                            smallestLsn is equals to current checkpoint log lsn,if
                            has active txns,it's euqals to smallest first_lsn of all
                            active txns. */
                        smallestLsn = fuzzyCkpLog.getSmallestLsn();
                    }
                    break;
                default:
                    //Adding TxnRegopLogRecord to redostack,and do its redo function for release txn resource of btree.
                    if (cursorLogRecord.getType() == LogRecord.LOG_TXN_REGOP) {
                        Integer txnid = new Integer(cursorLogRecord.getTxnId());
                        redoTable.put(txnid, txnid);
                    }

                    boolean doUNDO = false;
                    if (!redoTable.containsKey(new Integer(cursorLogRecord.getTxnId()))) {
                        doUNDO = true;
                    }

                    if (cursorLogRecord.getType() == LogRecord.LOG_DELETE_FILES) {
                        if (!redoTable.containsKey(new Integer(cursorLogRecord.getTxnId()))) {
                            Integer txnid = new Integer(cursorLogRecord.getTxnId());
                            redoTable.put(txnid, txnid);
                        }
                        doUNDO = false;
                    }

                    if (doUNDO) {
                        try {
                            cursorLogRecord.recover(LogRecord.UNDO);
                        } catch (ChaiDBException ie11) {
                            logger.error(ie11);
                            continue;
                        }
                    } else { //push into redo stack
                        redoStack.push(cursorLogRecord);
                        if (redoStack.size() == STACK_MAXSIZE) {
                            logger.info("Stack change. " + redoStack.size());

                            saveStack(cursorLsn);
                            logger.info(", New=" + redoStack.size() + " Stack" + (++stacks));
                        }

                    }
            }//switch

            if (cursorLsn.getOffset() == LogManager.FIRSTREC_PREVOFFSET || //current lsn is the first lsn of all log files
                    (smallestLsn != null && cursorLsn.compare(smallestLsn) == 0)//current lsn is equal to smallest lsn
                    ) {
                isEnd = true;
            }

            cursorLsn = new Lsn(cursorLsn.getFileId(), cursorLogRecord.getHeader().getPrevOffset());

        }//while

        if (countCkp == 0) {
            this.txnManager.setLastCkp(new Lsn(LogManager.FIRSTREC_LSN));
        }
        return true;
    }
}
TOP

Related Classes of org.chaidb.db.transaction.recover.NormalTransactionRecoverImpl

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.