📄 backup.cpp
字号:
/* Copyright (C) 2003 MySQL AB 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "Backup.hpp"#include <ndb_version.h>#include <NdbTCP.h>#include <Bitmask.hpp>#include <signaldata/NodeFailRep.hpp>#include <signaldata/ReadNodesConf.hpp>#include <signaldata/ScanFrag.hpp>#include <signaldata/GetTabInfo.hpp>#include <signaldata/DictTabInfo.hpp>#include <signaldata/ListTables.hpp>#include <signaldata/FsOpenReq.hpp>#include <signaldata/FsAppendReq.hpp>#include <signaldata/FsCloseReq.hpp>#include <signaldata/FsConf.hpp>#include <signaldata/FsRef.hpp>#include <signaldata/FsRemoveReq.hpp>#include <signaldata/BackupImpl.hpp>#include <signaldata/BackupSignalData.hpp>#include <signaldata/BackupContinueB.hpp>#include <signaldata/EventReport.hpp>#include <signaldata/UtilSequence.hpp>#include <signaldata/CreateTrig.hpp>#include <signaldata/AlterTrig.hpp>#include <signaldata/DropTrig.hpp>#include <signaldata/FireTrigOrd.hpp>#include <signaldata/TrigAttrInfo.hpp>#include <AttributeHeader.hpp>#include <signaldata/WaitGCP.hpp>#include <NdbTick.h>static NDB_TICKS startTime;static const Uint32 BACKUP_SEQUENCE = 0x1F000000;#ifdef VM_TRACE#define DEBUG_OUT(x) ndbout << x << endl#else#define DEBUG_OUT(x) #endif//#define DEBUG_ABORTstatic Uint32 g_TypeOfStart = NodeState::ST_ILLEGAL_TYPE;#define SEND_BACKUP_STARTED_FLAG(A) (((A) & 0x3) > 0)#define SEND_BACKUP_COMPLETED_FLAG(A) (((A) & 0x3) > 1)void Backup::execREAD_CONFIG_REQ(Signal* signal){ jamEntry(); const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); Uint32 ref = req->senderRef; Uint32 senderData = req->senderData; const ndb_mgm_configuration_iterator * p = theConfiguration.getOwnConfigIterator(); ndbrequire(p != 0); c_nodePool.setSize(MAX_NDB_NODES); Uint32 noBackups = 0, noTables = 0, noAttribs = 0, noFrags = 0; ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &m_diskless)); ndb_mgm_get_int_parameter(p, CFG_DB_PARALLEL_BACKUPS, &noBackups); // ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_TABLES, &noTables)); ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_TABLE, &noTables)); ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_ATTRIBUTES, &noAttribs)); ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_FRAG_CONNECT, &noFrags)); noAttribs++; //RT 527 bug fix c_backupPool.setSize(noBackups); c_backupFilePool.setSize(3 * noBackups); c_tablePool.setSize(noBackups * noTables); c_attributePool.setSize(noBackups * noAttribs); c_triggerPool.setSize(noBackups * 3 * noTables); c_fragmentPool.setSize(noBackups * noFrags); Uint32 szMem = 0; ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_MEM, &szMem); Uint32 noPages = (szMem + sizeof(Page32) - 1) / sizeof(Page32); // We need to allocate an additional of 2 pages. 1 page because of a bug in // ArrayPool and another one for DICTTAINFO. c_pagePool.setSize(noPages + NO_OF_PAGES_META_FILE + 2); Uint32 szDataBuf = (2 * 1024 * 1024); Uint32 szLogBuf = (2 * 1024 * 1024); Uint32 szWrite = 32768; ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_DATA_BUFFER_MEM, &szDataBuf); ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_LOG_BUFFER_MEM, &szLogBuf); ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_WRITE_SIZE, &szWrite); c_defaults.m_logBufferSize = szLogBuf; c_defaults.m_dataBufferSize = szDataBuf; c_defaults.m_minWriteSize = szWrite; c_defaults.m_maxWriteSize = szWrite; { // Init all tables ArrayList<Table> tables(c_tablePool); TablePtr ptr; while(tables.seize(ptr)){ new (ptr.p) Table(c_attributePool, c_fragmentPool); } tables.release(); } { ArrayList<BackupFile> ops(c_backupFilePool); BackupFilePtr ptr; while(ops.seize(ptr)){ new (ptr.p) BackupFile(* this, c_pagePool); } ops.release(); } { ArrayList<BackupRecord> recs(c_backupPool); BackupRecordPtr ptr; while(recs.seize(ptr)){ new (ptr.p) BackupRecord(* this, c_pagePool, c_tablePool, c_backupFilePool, c_triggerPool); } recs.release(); } // Initialize BAT for interface to file system { Page32Ptr p; ndbrequire(c_pagePool.seizeId(p, 0)); c_startOfPages = (Uint32 *)p.p; c_pagePool.release(p); NewVARIABLE* bat = allocateBat(1); bat[0].WA = c_startOfPages; bat[0].nrr = c_pagePool.getSize()*sizeof(Page32)/sizeof(Uint32); } ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); conf->senderRef = reference(); conf->senderData = senderData; sendSignal(ref, GSN_READ_CONFIG_CONF, signal, ReadConfigConf::SignalLength, JBB);}voidBackup::execSTTOR(Signal* signal) { jamEntry(); const Uint32 startphase = signal->theData[1]; const Uint32 typeOfStart = signal->theData[7]; if (startphase == 3) { jam(); g_TypeOfStart = typeOfStart; signal->theData[0] = reference(); sendSignal(NDBCNTR_REF, GSN_READ_NODESREQ, signal, 1, JBB); return; }//if if(startphase == 7 && g_TypeOfStart == NodeState::ST_INITIAL_START && c_masterNodeId == getOwnNodeId()){ jam(); createSequence(signal); return; }//if sendSTTORRY(signal); return;}//Dbdict::execSTTOR()voidBackup::execREAD_NODESCONF(Signal* signal){ jamEntry(); ReadNodesConf * conf = (ReadNodesConf *)signal->getDataPtr(); c_aliveNodes.clear(); Uint32 count = 0; for (Uint32 i = 0; i<MAX_NDB_NODES; i++) { jam(); if(NodeBitmask::get(conf->allNodes, i)){ jam(); count++; NodePtr node; ndbrequire(c_nodes.seize(node)); node.p->nodeId = i; if(NodeBitmask::get(conf->inactiveNodes, i)) { jam(); node.p->alive = 0; } else { jam(); node.p->alive = 1; c_aliveNodes.set(i); }//if }//if }//for c_masterNodeId = conf->masterNodeId; ndbrequire(count == conf->noOfNodes); sendSTTORRY(signal);}voidBackup::sendSTTORRY(Signal* signal){ signal->theData[0] = 0; signal->theData[3] = 1; signal->theData[4] = 3; signal->theData[5] = 7; signal->theData[6] = 255; // No more start phases from missra sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 7, JBB);}voidBackup::createSequence(Signal* signal){ UtilSequenceReq * req = (UtilSequenceReq*)signal->getDataPtrSend(); req->senderData = RNIL; req->sequenceId = BACKUP_SEQUENCE; req->requestType = UtilSequenceReq::Create; sendSignal(DBUTIL_REF, GSN_UTIL_SEQUENCE_REQ, signal, UtilSequenceReq::SignalLength, JBB);}voidBackup::execCONTINUEB(Signal* signal){ jamEntry(); const Uint32 Tdata0 = signal->theData[0]; const Uint32 Tdata1 = signal->theData[1]; const Uint32 Tdata2 = signal->theData[2]; switch(Tdata0) { case BackupContinueB::START_FILE_THREAD: case BackupContinueB::BUFFER_UNDERFLOW: { jam(); BackupFilePtr filePtr; c_backupFilePool.getPtr(filePtr, Tdata1); checkFile(signal, filePtr); return; } break; case BackupContinueB::BUFFER_FULL_SCAN: { jam(); BackupFilePtr filePtr; c_backupFilePool.getPtr(filePtr, Tdata1); checkScan(signal, filePtr); return; } break; case BackupContinueB::BUFFER_FULL_FRAG_COMPLETE: { jam(); BackupFilePtr filePtr; c_backupFilePool.getPtr(filePtr, Tdata1); fragmentCompleted(signal, filePtr); return; } break; case BackupContinueB::BUFFER_FULL_META: { jam(); BackupRecordPtr ptr; c_backupPool.getPtr(ptr, Tdata1); BackupFilePtr filePtr; ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr); FsBuffer & buf = filePtr.p->operation.dataBuffer; if(buf.getFreeSize() + buf.getMinRead() < buf.getUsableSize()) { jam(); TablePtr tabPtr; c_tablePool.getPtr(tabPtr, Tdata2); DEBUG_OUT("Backup - Buffer full - " << buf.getFreeSize() << " + " << buf.getMinRead() << " < " << buf.getUsableSize() << " - tableId = " << tabPtr.p->tableId); signal->theData[0] = BackupContinueB::BUFFER_FULL_META; signal->theData[1] = Tdata1; signal->theData[2] = Tdata2; sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 3); return; }//if TablePtr tabPtr; c_tablePool.getPtr(tabPtr, Tdata2); GetTabInfoReq * req = (GetTabInfoReq *)signal->getDataPtrSend(); req->senderRef = reference(); req->senderData = ptr.i; req->requestType = GetTabInfoReq::RequestById | GetTabInfoReq::LongSignalConf; req->tableId = tabPtr.p->tableId; sendSignal(DBDICT_REF, GSN_GET_TABINFOREQ, signal, GetTabInfoReq::SignalLength, JBB); return; } default: ndbrequire(0); }//switch}voidBackup::execDUMP_STATE_ORD(Signal* signal){ jamEntry(); if(signal->theData[0] == 20){ if(signal->length() > 1){ c_defaults.m_dataBufferSize = (signal->theData[1] * 1024 * 1024); } if(signal->length() > 2){ c_defaults.m_logBufferSize = (signal->theData[2] * 1024 * 1024); } if(signal->length() > 3){ c_defaults.m_minWriteSize = signal->theData[3] * 1024; } if(signal->length() > 4){ c_defaults.m_maxWriteSize = signal->theData[4] * 1024; } infoEvent("Backup: data: %d log: %d min: %d max: %d", c_defaults.m_dataBufferSize, c_defaults.m_logBufferSize, c_defaults.m_minWriteSize, c_defaults.m_maxWriteSize); return; } if(signal->theData[0] == 21){ BackupReq * req = (BackupReq*)signal->getDataPtrSend(); req->senderData = 23; req->backupDataLen = 0; sendSignal(BACKUP_REF, GSN_BACKUP_REQ,signal,BackupReq::SignalLength, JBB); startTime = NdbTick_CurrentMillisecond(); return; } if(signal->theData[0] == 22){ const Uint32 seq = signal->theData[1]; FsRemoveReq * req = (FsRemoveReq *)signal->getDataPtrSend(); req->userReference = reference(); req->userPointer = 23; req->directory = 1; req->ownDirectory = 1; FsOpenReq::setVersion(req->fileNumber, 2); FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_CTL); FsOpenReq::v2_setSequence(req->fileNumber, seq); FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId()); sendSignal(NDBFS_REF, GSN_FSREMOVEREQ, signal, FsRemoveReq::SignalLength, JBA); return; } if(signal->theData[0] == 23){ /** * Print records */ BackupRecordPtr ptr; for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr)){ infoEvent("BackupRecord %d: BackupId: %d MasterRef: %x ClientRef: %x", ptr.i, ptr.p->backupId, ptr.p->masterRef, ptr.p->clientRef); infoEvent(" State: %d", ptr.p->slaveState.getState()); BackupFilePtr filePtr; for(ptr.p->files.first(filePtr); filePtr.i != RNIL; ptr.p->files.next(filePtr)){ jam(); infoEvent(" file %d: type: %d open: %d running: %d done: %d scan: %d", filePtr.i, filePtr.p->fileType, filePtr.p->fileOpened, filePtr.p->fileRunning, filePtr.p->fileClosing, filePtr.p->scanRunning); } } } if(signal->theData[0] == 24){ /** * Print size of records etc. */ infoEvent("Backup - dump pool sizes"); infoEvent("BackupPool: %d BackupFilePool: %d TablePool: %d", c_backupPool.getSize(), c_backupFilePool.getSize(), c_tablePool.getSize()); infoEvent("AttrPool: %d TriggerPool: %d FragmentPool: %d", c_backupPool.getSize(), c_backupFilePool.getSize(), c_tablePool.getSize()); infoEvent("PagePool: %d", c_pagePool.getSize()); if(signal->getLength() == 2 && signal->theData[1] == 2424) { ndbrequire(c_tablePool.getSize() == c_tablePool.getNoOfFree()); ndbrequire(c_attributePool.getSize() == c_attributePool.getNoOfFree()); ndbrequire(c_backupPool.getSize() == c_backupPool.getNoOfFree()); ndbrequire(c_backupFilePool.getSize() == c_backupFilePool.getNoOfFree()); ndbrequire(c_pagePool.getSize() == c_pagePool.getNoOfFree()); ndbrequire(c_fragmentPool.getSize() == c_fragmentPool.getNoOfFree()); ndbrequire(c_triggerPool.getSize() == c_triggerPool.getNoOfFree()); } }}boolBackup::findTable(const BackupRecordPtr & ptr, TablePtr & tabPtr, Uint32 tableId) const{ for(ptr.p->tables.first(tabPtr); tabPtr.i != RNIL; ptr.p->tables.next(tabPtr)) { jam(); if(tabPtr.p->tableId == tableId){ jam(); return true; }//if }//for tabPtr.i = RNIL; tabPtr.p = 0; return false;}static Uint32 xps(Uint32 x, Uint64 ms){ float fx = x; float fs = ms; if(ms == 0 || x == 0) { jam(); return 0; }//if jam(); return ((Uint32)(1000.0f * (fx + fs/2.1f))) / ((Uint32)fs);}struct Number { Number(Uint32 r) { val = r;} Number & operator=(Uint32 r) { val = r; return * this; } Uint32 val;};NdbOut &operator<< (NdbOut & out, const Number & val){ char p = 0; Uint32 loop = 1; while(val.val > loop){ loop *= 1000; p += 3; } if(loop != 1){ p -= 3; loop /= 1000; } switch(p){ case 0: break; case 3: p = 'k'; break; case 6: p = 'M'; break; case 9:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -