1
/* Copyright (C) 2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
17
#include <ndb_global.h>
19
#include "NdbApiSignal.hpp"
20
#include "NdbImpl.hpp"
21
#include <NdbOperation.hpp>
22
#include <NdbTransaction.hpp>
23
#include <NdbRecAttr.hpp>
24
#include <IPCConfig.hpp>
25
#include "TransporterFacade.hpp"
26
#include <ConfigRetriever.hpp>
27
#include <ndb_limits.h>
30
#include "ObjectMap.hpp"
31
#include <NdbIndexScanOperation.hpp>
32
#include <NdbIndexOperation.hpp>
33
#include "NdbUtil.hpp"
34
#include <NdbBlob.hpp>
35
#include "NdbEventOperationImpl.hpp"
37
#include <EventLogger.hpp>
38
extern EventLogger g_eventLogger;
40
Ndb::Ndb( Ndb_cluster_connection *ndb_cluster_connection,
41
const char* aDataBase , const char* aSchema)
44
DBUG_ENTER("Ndb::Ndb()");
45
DBUG_PRINT("enter",("Ndb::Ndb this: 0x%lx", (long) this));
46
setup(ndb_cluster_connection, aDataBase, aSchema);
50
void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection,
51
const char* aDataBase , const char* aSchema)
53
DBUG_ENTER("Ndb::setup");
55
assert(theImpl == NULL);
56
theImpl= new NdbImpl(ndb_cluster_connection,*this);
57
theDictionary= &(theImpl->m_dictionary);
59
thePreparedTransactionsArray= NULL;
60
theSentTransactionsArray= NULL;
61
theCompletedTransactionsArray= NULL;
62
theNoOfPreparedTransactions= 0;
63
theNoOfSentTransactions= 0;
64
theNoOfCompletedTransactions= 0;
65
theRemainingStartTransactions= 0;
66
theMaxNoOfTransactions= 0;
67
theMinNoOfEventsToWakeUp= 0;
68
theTransactionList= NULL;
69
theConnectionArray= NULL;
70
the_last_check_time= 0;
73
theNdbBlockNumber= -1;
74
theInitState= NotConstructed;
80
cond_wait_index = TransporterFacade::MAX_NO_THREADS;
81
cond_signal_ndb = NULL;
83
fullyQualifiedNames = true;
94
theConnectionArray = new NdbConnection * [MAX_NDB_NODES];
95
theCommitAckSignal = NULL;
98
for (i = 0; i < MAX_NDB_NODES ; i++) {
99
theConnectionArray[i] = NULL;
103
theImpl->m_dbname.assign(aDataBase);
104
theImpl->m_schemaname.assign(aSchema);
105
theImpl->update_prefix();
107
theImpl->theWaiter.m_mutex = theImpl->m_transporter_facade->theMutexPtr;
109
// Signal that the constructor has finished OK
110
if (theInitState == NotConstructed)
111
theInitState = NotInitialised;
114
// theImpl->theWaiter.m_mutex must be set before this
115
theEventBuffer= new NdbEventBuffer(this);
116
if (theEventBuffer == NULL) {
117
ndbout_c("Failed NdbEventBuffer()");
126
/*****************************************************************************
129
* Remark: Disconnect with the database.
130
*****************************************************************************/
133
DBUG_ENTER("Ndb::~Ndb()");
134
DBUG_PRINT("enter",("this: 0x%lx", (long) this));
137
getDictionary()->removeTableGlobal(*m_sys_tab_0, 0);
139
assert(theImpl->m_ev_op == 0); // user should return NdbEventOperation's
140
for (NdbEventOperationImpl *op= theImpl->m_ev_op; op; op=op->m_next)
142
if (op->m_state == NdbEventOperation::EO_EXECUTING && op->stop())
143
g_eventLogger.error("stopping NdbEventOperation failed in Ndb destructor");
144
op->m_magic_number= 0;
148
/* Disconnect from transporter to stop signals from coming in */
149
if (theImpl->m_transporter_facade != NULL && theNdbBlockNumber > 0){
150
theImpl->m_transporter_facade->close(theNdbBlockNumber, theFirstTransId);
153
delete theEventBuffer;
155
releaseTransactionArrays();
157
delete []theConnectionArray;
158
if(theCommitAckSignal != NULL){
159
delete theCommitAckSignal;
160
theCommitAckSignal = NULL;
165
#ifdef POORMANSPURIFY
167
ndbout << "cnewSignals=" << cnewSignals << endl;
168
ndbout << "cfreeSignals=" << cfreeSignals << endl;
169
ndbout << "cgetSignals=" << cgetSignals << endl;
170
ndbout << "creleaseSignals=" << creleaseSignals << endl;
172
// Poor mans purifier
173
assert(cnewSignals == cfreeSignals);
174
assert(cgetSignals == creleaseSignals);
179
NdbWaiter::NdbWaiter(){
184
m_cond_wait_index= TransporterFacade::MAX_NO_THREADS;
185
m_condition = NdbCondition_Create();
188
NdbWaiter::~NdbWaiter(){
189
NdbCondition_Destroy(m_condition);
192
NdbImpl::NdbImpl(Ndb_cluster_connection *ndb_cluster_connection,
195
m_ndb_cluster_connection(ndb_cluster_connection->m_impl),
196
m_transporter_facade(ndb_cluster_connection->m_impl.m_transporter_facade),
198
theCurrentConnectIndex(0),
199
theNdbObjectIdMap(m_transporter_facade->theMutexPtr,
205
for (i = 0; i < MAX_NDB_NODES; i++) {
206
the_release_ind[i] = 0;
208
m_optimized_node_selection=
209
m_ndb_cluster_connection.m_optimized_node_selection;
211
m_systemPrefix.assfmt("%s%c%s%c", NDB_SYSTEM_DATABASE, table_name_separator,
212
NDB_SYSTEM_SCHEMA, table_name_separator);