transactd 3.4.1 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CMakeLists.txt +2 -2
- data/bin/common/tdclc_32_3_5.dll +0 -0
- data/bin/common/tdclc_64_3_5.dll +0 -0
- data/build/common/options.cmake +12 -0
- data/build/common/transactd_cl_common.cmake +1 -0
- data/build/common/transactd_required.cmake +5 -0
- data/build/swig/ruby/tdclrb_wrap.cpp +1029 -130
- data/build/swig/tdcl.i +60 -5
- data/build/tdclc/CMakeLists.txt +30 -32
- data/build/tdclc/libtdclcm.map +1 -1
- data/build/tdclc/tdclc.cbproj +1 -1
- data/build/tdclc/tdclc.rc +4 -4
- data/build/tdclcpp/CMakeLists.txt +39 -48
- data/build/tdclcpp/tdclcpp.rc +4 -4
- data/build/tdclcpp/tdclcpp_bc.cbproj +4 -1
- data/build/tdclrb/CMakeLists.txt +5 -4
- data/build/tdclrb/tdclrb.rc +4 -4
- data/source/bzs/db/engine/mysql/database.cpp +45 -35
- data/source/bzs/db/engine/mysql/database.h +6 -8
- data/source/bzs/db/engine/mysql/dbManager.cpp +11 -0
- data/source/bzs/db/engine/mysql/dbManager.h +1 -0
- data/source/bzs/db/engine/mysql/ha.cpp +174 -0
- data/source/bzs/db/engine/mysql/ha.h +50 -0
- data/source/bzs/db/engine/mysql/mysqlInternal.h +18 -1
- data/source/bzs/db/engine/mysql/mysqlProtocol.cpp +222 -9
- data/source/bzs/db/engine/mysql/mysqlProtocol.h +5 -0
- data/source/bzs/db/protocol/tdap/client/client.cpp +23 -9
- data/source/bzs/db/protocol/tdap/client/client.h +125 -94
- data/source/bzs/db/protocol/tdap/client/connMgr.cpp +139 -30
- data/source/bzs/db/protocol/tdap/client/connMgr.h +40 -8
- data/source/bzs/db/protocol/tdap/client/database.cpp +17 -17
- data/source/bzs/db/protocol/tdap/client/database.h +15 -0
- data/source/bzs/db/protocol/tdap/client/dllmain.cpp +10 -4
- data/source/bzs/db/protocol/tdap/client/haNameResolver.cpp +486 -0
- data/source/bzs/db/protocol/tdap/client/haNameResolver.h +74 -0
- data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +102 -71
- data/source/bzs/db/protocol/tdap/client/nsDatabase.h +15 -3
- data/source/bzs/db/protocol/tdap/client/nsTable.cpp +2 -5
- data/source/bzs/db/protocol/tdap/client/nsTable.h +2 -1
- data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +2 -2
- data/source/bzs/db/protocol/tdap/client/table.cpp +1 -2
- data/source/bzs/db/protocol/tdap/client/trdboostapi.h +13 -0
- data/source/bzs/db/protocol/tdap/client/trnsctcl.def +1 -0
- data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +9 -7
- data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +2 -2
- data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +328 -117
- data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +7 -8
- data/source/bzs/db/protocol/tdap/tdapcapi.h +81 -41
- data/source/bzs/db/transactd/connManager.cpp +118 -93
- data/source/bzs/db/transactd/connManager.h +6 -1
- data/source/bzs/db/transactd/connectionRecord.h +27 -7
- data/source/bzs/db/transactd/transactd.cpp +24 -13
- data/source/bzs/env/crosscompile.h +2 -0
- data/source/bzs/netsvc/client/iconnection.h +2 -0
- data/source/bzs/netsvc/client/tcpClient.cpp +45 -14
- data/source/bzs/netsvc/client/tcpClient.h +21 -4
- data/source/bzs/netsvc/server/IAppModule.h +1 -0
- data/source/bzs/netsvc/server/serverCpt.cpp +1 -1
- data/source/bzs/netsvc/server/serverPipe.cpp +2 -0
- data/source/bzs/netsvc/server/serverTpool.cpp +3 -5
- data/source/bzs/test/tdclatl/test_v3.js +91 -3
- data/source/bzs/test/tdclphp/transactd_v3_Test.php +89 -3
- data/source/bzs/test/tdclrb/transactd_v3_spec.rb +69 -2
- data/source/bzs/test/trdclengn/testField.h +19 -1
- data/source/bzs/test/trdclengn/test_tdclcpp_ha.cpp +388 -0
- data/source/bzs/test/trdclengn/test_tdclcpp_v3.cpp +6 -1
- data/source/bzs/test/trdclengn/test_trdclengn.cpp +1 -0
- data/source/bzs/test/trdclengn/testbase.h +7 -1
- data/source/global/replication/haCommand.cpp +843 -0
- data/source/global/replication/haCommand.h +78 -0
- data/source/global/replication/haMgr.cpp +321 -0
- data/source/global/replication/replCommand.cpp +696 -0
- data/source/global/replication/replCommand.h +161 -0
- data/source/global/tdclatl/BinlogPos.cpp +10 -0
- data/source/global/tdclatl/BinlogPos.h +1 -0
- data/source/global/tdclatl/ConnMgr.cpp +89 -2
- data/source/global/tdclatl/ConnMgr.h +13 -1
- data/source/global/tdclatl/ConnRecord.cpp +8 -2
- data/source/global/tdclatl/ConnRecord.h +4 -3
- data/source/global/tdclatl/Database.cpp +13 -0
- data/source/global/tdclatl/Database.h +2 -0
- data/source/global/tdclatl/HaNameREsolver.cpp +54 -0
- data/source/global/tdclatl/HaNameREsolver.h +68 -0
- data/source/global/tdclatl/resource.h +0 -0
- data/source/global/tdclatl/tdclatl.idl +76 -5
- metadata +16 -6
- data/bin/common/tdclc_32_3_4.dll +0 -0
- data/bin/common/tdclc_64_3_4.dll +0 -0
- data/source/bzs/db/protocol/tdap/mysql/debuglog.cpp +0 -423
- data/source/bzs/db/protocol/tdap/mysql/debuglog.h +0 -116
|
@@ -53,14 +53,33 @@ public:
|
|
|
53
53
|
connRecords();
|
|
54
54
|
connRecords(const connRecords& r);
|
|
55
55
|
connRecords& operator=(const connRecords& r);
|
|
56
|
-
const record& operator[] (
|
|
57
|
-
record& operator[] (
|
|
56
|
+
const record& operator[] (size_t index) const;
|
|
57
|
+
record& operator[] (size_t index);
|
|
58
58
|
size_t size() const;
|
|
59
59
|
void clear();
|
|
60
60
|
void release();
|
|
61
61
|
static connRecords* create();
|
|
62
|
+
static connRecords* create(const connRecords& r);
|
|
62
63
|
};
|
|
63
64
|
|
|
65
|
+
typedef boost::shared_ptr<connRecords> connRecords_ptr;
|
|
66
|
+
|
|
67
|
+
inline void releaseConnRecords(connRecords* p)
|
|
68
|
+
{
|
|
69
|
+
if (p) p->release();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
inline connRecords_ptr createConnRecords(const connRecords& r)
|
|
73
|
+
{
|
|
74
|
+
return connRecords_ptr(connRecords::create(r), releaseConnRecords);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
inline connRecords_ptr createConnRecords()
|
|
78
|
+
{
|
|
79
|
+
return connRecords_ptr(connRecords::create(), releaseConnRecords);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
64
83
|
class DLLLIB connMgr : private nstable // no copyable
|
|
65
84
|
{
|
|
66
85
|
|
|
@@ -85,7 +104,7 @@ private:
|
|
|
85
104
|
const connMgr::records& doDefinedTables(const _TCHAR* dbname, int type);
|
|
86
105
|
void setBlobFieldPointer(const bzs::db::blobHeader* bd);
|
|
87
106
|
explicit connMgr(database* db);
|
|
88
|
-
|
|
107
|
+
const records& blobOperation(int op);
|
|
89
108
|
public:
|
|
90
109
|
|
|
91
110
|
bool connect(const _TCHAR* uri);
|
|
@@ -94,22 +113,35 @@ public:
|
|
|
94
113
|
const records& tables(const _TCHAR* dbname);
|
|
95
114
|
const records& views(const _TCHAR* dbname);
|
|
96
115
|
const records& schemaTables(const _TCHAR* dbname);
|
|
97
|
-
const records& slaveStatus();
|
|
116
|
+
const records& slaveStatus(const char* channel=0);
|
|
117
|
+
#ifdef _UNICODE
|
|
118
|
+
const records& slaveStatus(const wchar_t* channel);
|
|
119
|
+
#endif
|
|
120
|
+
const records& channels(bool withLock = false);
|
|
121
|
+
const records& slaveHosts();
|
|
98
122
|
const records& sysvars();
|
|
123
|
+
const records& extendedvars();
|
|
99
124
|
const records& statusvars();
|
|
100
125
|
const records& connections();
|
|
101
126
|
const records& inUseDatabases(__int64 connid);
|
|
102
127
|
const records& inUseTables(__int64 connid, int dbid);
|
|
103
128
|
void postDisconnectOne(__int64 connid);
|
|
104
129
|
void postDisconnectAll();
|
|
105
|
-
|
|
130
|
+
bool haLock();
|
|
131
|
+
void haUnlock();
|
|
132
|
+
bool setRole(int v);
|
|
133
|
+
bool setTrxBlock(bool v);
|
|
134
|
+
bool setEnableFailover(bool v);
|
|
106
135
|
database* db() const;
|
|
107
|
-
const _TCHAR* slaveStatusName(uint_td
|
|
136
|
+
const _TCHAR* slaveStatusName(uint_td id) const;
|
|
137
|
+
using nstable::stat;
|
|
108
138
|
using nstable::tdapErr;
|
|
109
139
|
using nstable::release;
|
|
140
|
+
using nstable::isOpen;
|
|
110
141
|
static void removeSystemDb(records& recs);
|
|
111
|
-
static const _TCHAR* sysvarName(uint_td
|
|
112
|
-
static const _TCHAR* statusvarName(uint_td
|
|
142
|
+
static const _TCHAR* sysvarName(uint_td id);
|
|
143
|
+
static const _TCHAR* statusvarName(uint_td id);
|
|
144
|
+
static const _TCHAR* extendedVarName(uint_td id);
|
|
113
145
|
static connMgr* create(database* db);
|
|
114
146
|
};
|
|
115
147
|
|
|
@@ -258,8 +258,8 @@ void database::create(const _TCHAR* uri, short type)
|
|
|
258
258
|
_TCHAR posblk[128] = { 0x00 };
|
|
259
259
|
const char* p = toServerUri((char*)buf, MAX_PATH, uri_tmp, true);
|
|
260
260
|
uint_td len = 0;
|
|
261
|
-
stat =
|
|
262
|
-
(void*)p, (uchar_td)strlen(p), CR_SUBOP_CREATE_DBONLY
|
|
261
|
+
stat = tdapEx(TD_CREATETABLE, posblk, NULL, &len,
|
|
262
|
+
(void*)p, (uchar_td)strlen(p), CR_SUBOP_CREATE_DBONLY);
|
|
263
263
|
}
|
|
264
264
|
}
|
|
265
265
|
else
|
|
@@ -440,6 +440,12 @@ void database::doOpen(const _TCHAR* uri, short type, short mode,
|
|
|
440
440
|
m_impl->isOpened = (m_stat == STATUS_SUCCESS); // important
|
|
441
441
|
}
|
|
442
442
|
|
|
443
|
+
bool isConnected(const uchar_td* cid)
|
|
444
|
+
{
|
|
445
|
+
const void* p = *((void**)cid);
|
|
446
|
+
return p != 0;
|
|
447
|
+
}
|
|
448
|
+
|
|
443
449
|
bool database::open(const _TCHAR* _uri, short type, short mode,
|
|
444
450
|
const _TCHAR* dir, const _TCHAR* ownername)
|
|
445
451
|
{
|
|
@@ -492,7 +498,7 @@ bool database::open(const _TCHAR* _uri, short type, short mode,
|
|
|
492
498
|
{
|
|
493
499
|
if ((compatibleMode() & CMP_MODE_MYSQL_NULL) == 0)
|
|
494
500
|
m_stat = STATUS_INVALID_NULLMODE;
|
|
495
|
-
else if (isAssociate() || connect(_uri))
|
|
501
|
+
else if (isAssociate() || isConnected(clientID()) || connect(_uri))
|
|
496
502
|
{
|
|
497
503
|
m_impl->dbDef->allocDatabuffer();
|
|
498
504
|
m_stat = m_impl->dbDef->stat();
|
|
@@ -554,8 +560,7 @@ short database::aclReload()
|
|
|
554
560
|
return m_stat = STATUS_DB_YET_OPEN;
|
|
555
561
|
_TCHAR posblk[128] = { 0x00 };
|
|
556
562
|
uint_td buflen = 0;
|
|
557
|
-
return m_stat =
|
|
558
|
-
m_btrcallid(TD_ACL_RELOAD, posblk, NULL, &buflen, 0, 0, 0, clientID());
|
|
563
|
+
return m_stat = tdapEx(TD_ACL_RELOAD, posblk, NULL, &buflen, 0, 0, 0);
|
|
559
564
|
}
|
|
560
565
|
|
|
561
566
|
char* database::getContinuousList(int option)
|
|
@@ -594,8 +599,7 @@ short database::continuous(char_td IsEnd, bool inclideRepfile)
|
|
|
594
599
|
char tmp[128] = { 0x00 };
|
|
595
600
|
char* buf = getContinuousList(inclideRepfile);
|
|
596
601
|
uint_td buflen = (uint_td)strlen(buf) + 1;
|
|
597
|
-
m_stat =
|
|
598
|
-
m_btrcallid(TD_BACKUPMODE, tmp, buf, &buflen, 0, 0, IsEnd, clientID());
|
|
602
|
+
m_stat = tdap(TD_BACKUPMODE, tmp, buf, &buflen, 0, 0, IsEnd);
|
|
599
603
|
free(buf);
|
|
600
604
|
return m_stat;
|
|
601
605
|
}
|
|
@@ -994,10 +998,8 @@ char* database::getSqlStringForCreateTable(const _TCHAR* tableName, char* retbuf
|
|
|
994
998
|
|
|
995
999
|
const char* p = toServerUri(buf2, MAX_PATH, uri, isUseTransactd());
|
|
996
1000
|
|
|
997
|
-
m_stat =
|
|
998
|
-
|
|
999
|
-
size, (void*)p, (uchar_td)strlen(p),
|
|
1000
|
-
ST_SUB_GETSQL_BY_TABLEDEF, clientID());
|
|
1001
|
+
m_stat = tdap(TD_TABLE_INFO, posblk, td, size, (void*)p,
|
|
1002
|
+
(uchar_td)strlen(p), ST_SUB_GETSQL_BY_TABLEDEF);
|
|
1001
1003
|
return retbuf;
|
|
1002
1004
|
}
|
|
1003
1005
|
|
|
@@ -1014,10 +1016,10 @@ bool database::createTable(const char* utf8Sql)
|
|
|
1014
1016
|
_TCHAR posblk[128] = { 0x00 };
|
|
1015
1017
|
const char* p = toServerUri(buf2, MAX_PATH, rootDir(), true);
|
|
1016
1018
|
uint_td len = (uint_td)strlen(utf8Sql);
|
|
1017
|
-
m_stat =
|
|
1019
|
+
m_stat = tdapEx(TD_CREATETABLE, posblk, (void*)utf8Sql, &len,
|
|
1018
1020
|
(void*)p, (uchar_td)strlen(p),
|
|
1019
1021
|
(m_impl->createExistNoCheck) ?
|
|
1020
|
-
CR_SUBOP_BY_SQL : CR_SUBOP_BY_SQL_NOCKECK
|
|
1022
|
+
CR_SUBOP_BY_SQL : CR_SUBOP_BY_SQL_NOCKECK);
|
|
1021
1023
|
}
|
|
1022
1024
|
}
|
|
1023
1025
|
else
|
|
@@ -1044,12 +1046,10 @@ bool database::createTable(short fileNum, const _TCHAR* uri)
|
|
|
1044
1046
|
|
|
1045
1047
|
const char* p = toServerUri(buf2, MAX_PATH, uri, isUseTransactd());
|
|
1046
1048
|
|
|
1047
|
-
m_stat =
|
|
1048
|
-
TD_CREATETABLE, posblk, td,
|
|
1049
|
+
m_stat = tdapEx(TD_CREATETABLE, posblk, td,
|
|
1049
1050
|
&m_impl->dbDef->m_datalen, (void*)p, (uchar_td)strlen(p),
|
|
1050
1051
|
(m_impl->createExistNoCheck) ?
|
|
1051
|
-
CR_SUBOP_BY_TABLEDEF : CR_SUBOP_BY_TABLEDEF_NOCKECK
|
|
1052
|
-
clientID());
|
|
1052
|
+
CR_SUBOP_BY_TABLEDEF : CR_SUBOP_BY_TABLEDEF_NOCKECK);
|
|
1053
1053
|
}
|
|
1054
1054
|
else
|
|
1055
1055
|
{
|
|
@@ -149,6 +149,21 @@ public:
|
|
|
149
149
|
static const int CMP_MODE_OLD_NULL = 0;
|
|
150
150
|
};
|
|
151
151
|
|
|
152
|
+
class overrideCompatibleMode
|
|
153
|
+
{
|
|
154
|
+
int mode;
|
|
155
|
+
public:
|
|
156
|
+
inline overrideCompatibleMode(int v)
|
|
157
|
+
{
|
|
158
|
+
mode = database::compatibleMode();
|
|
159
|
+
database::setCompatibleMode(v);
|
|
160
|
+
}
|
|
161
|
+
inline ~overrideCompatibleMode()
|
|
162
|
+
{
|
|
163
|
+
database::setCompatibleMode(mode);
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
152
167
|
} // namespace client
|
|
153
168
|
} // namespace tdap
|
|
154
169
|
} // namespace protocol
|
|
@@ -350,7 +350,7 @@ extern "C" PACKAGE_OSX short_td __STDCALL
|
|
|
350
350
|
else
|
|
351
351
|
{
|
|
352
352
|
client_t->cleanup();
|
|
353
|
-
return
|
|
353
|
+
return client_t->result();
|
|
354
354
|
}
|
|
355
355
|
}
|
|
356
356
|
else if (op == TD_OPENTABLE)
|
|
@@ -358,7 +358,7 @@ extern "C" PACKAGE_OSX short_td __STDCALL
|
|
|
358
358
|
if (!client_t->buildDualChasetKeybuf())
|
|
359
359
|
{
|
|
360
360
|
client_t->cleanup();
|
|
361
|
-
return
|
|
361
|
+
return client_t->result();
|
|
362
362
|
}
|
|
363
363
|
}
|
|
364
364
|
break;
|
|
@@ -461,7 +461,7 @@ const char* dateTimeStr(char* buf, unsigned int bufsize)
|
|
|
461
461
|
date = &tmp;
|
|
462
462
|
localtime_x(date, &now);
|
|
463
463
|
#endif // NOT __MINGW32__
|
|
464
|
-
sprintf_s(buf, bufsize, "%04d
|
|
464
|
+
sprintf_s(buf, bufsize, "%04d-%02d-%02dT%02d:%02d:%02d",
|
|
465
465
|
date->tm_year + 1900, date->tm_mon + 1, date->tm_mday,
|
|
466
466
|
date->tm_hour, date->tm_min, date->tm_sec);
|
|
467
467
|
return buf;
|
|
@@ -482,7 +482,7 @@ void writeErrorLog(int err, const char* msg)
|
|
|
482
482
|
strcpy_s(buf, MAX_PATH, "/var/log");
|
|
483
483
|
#endif
|
|
484
484
|
|
|
485
|
-
strcat_s(buf, MAX_PATH, PSEPARATOR
|
|
485
|
+
strcat_s(buf, MAX_PATH, PSEPARATOR TD_CLINET_LOGNAME);
|
|
486
486
|
FILE* fp = fileOpen(buf, "a+");
|
|
487
487
|
if (fp)
|
|
488
488
|
{
|
|
@@ -561,3 +561,9 @@ extern "C" PACKAGE_OSX void __STDCALL BeginWinThreadPoolShutdown()
|
|
|
561
561
|
{
|
|
562
562
|
win_thread_pool_shutdown = true;
|
|
563
563
|
}
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
extern "C" PACKAGE_OSX void __STDCALL RegisterHaNameResolver(HANAME_RESOLVER_PTR func)
|
|
567
|
+
{
|
|
568
|
+
m_cons->registHaNameResolver(func);
|
|
569
|
+
}
|
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
/* =================================================================
|
|
2
|
+
Copyright (C) 2016 BizStation Corp All rights reserved.
|
|
3
|
+
|
|
4
|
+
This program is free software; you can redistribute it and/or
|
|
5
|
+
modify it under the terms of the GNU General Public License
|
|
6
|
+
as published by the Free Software Foundation; either version 2
|
|
7
|
+
of the License, or (at your option) any later version.
|
|
8
|
+
|
|
9
|
+
This program is distributed in the hope that it will be useful,
|
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
GNU General Public License for more details.
|
|
13
|
+
|
|
14
|
+
You should have received a copy of the GNU General Public License
|
|
15
|
+
along with this program; if not, write to the Free Software
|
|
16
|
+
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
17
|
+
02111-1307, USA.
|
|
18
|
+
================================================================= */
|
|
19
|
+
#if defined(__BORLANDC__) && defined(__clang__)
|
|
20
|
+
#define BOOST_THREAD_BUILD_DLL
|
|
21
|
+
#endif
|
|
22
|
+
#include <boost/thread.hpp>
|
|
23
|
+
#include <boost/scoped_ptr.hpp>
|
|
24
|
+
#include "haNameResolver.h"
|
|
25
|
+
#include <bzs/env/compiler.h>
|
|
26
|
+
#include <vector>
|
|
27
|
+
#include <string>
|
|
28
|
+
#include <algorithm>
|
|
29
|
+
#include "nsDatabase.h"
|
|
30
|
+
#include "database.h"
|
|
31
|
+
#include "connMgr.h"
|
|
32
|
+
#ifdef _WIN32
|
|
33
|
+
#include <Shlobj.h>
|
|
34
|
+
#include <direct.h>
|
|
35
|
+
#endif
|
|
36
|
+
|
|
37
|
+
#ifdef __BCPLUSPLUS__
|
|
38
|
+
# pragma package(smart_init)
|
|
39
|
+
# define BZS_LINK_BOOST_THREAD
|
|
40
|
+
# define BZS_LINK_BOOST_FILESYSTEM
|
|
41
|
+
# define BZS_LINK_BOOST_SYSTEM
|
|
42
|
+
# ifdef _WIN64
|
|
43
|
+
# define BZS_LINK_BOOST_CHRONO
|
|
44
|
+
namespace boost { void tss_cleanup_implemented(){} }
|
|
45
|
+
# else
|
|
46
|
+
namespace boost { extern "C" void tss_cleanup_implemented() {} }
|
|
47
|
+
# endif //_WIN64
|
|
48
|
+
# include <bzs/env/boost_bcb_link.h>
|
|
49
|
+
#endif // __BCPLUSPLUS__
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
using namespace std;
|
|
54
|
+
boost::mutex g_nr_mutex;
|
|
55
|
+
static string masterRoleName;
|
|
56
|
+
static vector<string> slaveRoleNames;
|
|
57
|
+
static vector<string> slaveHosts;
|
|
58
|
+
|
|
59
|
+
static string user;
|
|
60
|
+
static string passwd;
|
|
61
|
+
|
|
62
|
+
namespace bzs
|
|
63
|
+
{
|
|
64
|
+
namespace db
|
|
65
|
+
{
|
|
66
|
+
namespace protocol
|
|
67
|
+
{
|
|
68
|
+
namespace tdap
|
|
69
|
+
{
|
|
70
|
+
namespace client
|
|
71
|
+
{
|
|
72
|
+
|
|
73
|
+
const char* __STDCALL hostNameResolver(const char* vhost, const char* port, char* buf, unsigned int& opt);
|
|
74
|
+
struct portMap
|
|
75
|
+
{
|
|
76
|
+
short myPort;
|
|
77
|
+
short tdPort;
|
|
78
|
+
portMap(short m, short td) : myPort(m), tdPort(td){}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
static database* g_db=NULL;
|
|
82
|
+
static connMgr* g_mgr = NULL;
|
|
83
|
+
static connMgr::records g_recs;
|
|
84
|
+
static vector<portMap> g_portMap;
|
|
85
|
+
static string cache_master;
|
|
86
|
+
static string cache_slave;
|
|
87
|
+
static int g_slaveIndex = 0;
|
|
88
|
+
static short g_stat = 0;
|
|
89
|
+
static short g_slaveNum = 0;
|
|
90
|
+
static bool g_failover = false;
|
|
91
|
+
static bool g_failoverError = false;
|
|
92
|
+
static bool g_callFailover = true;
|
|
93
|
+
static bool g_readonly_control = false;
|
|
94
|
+
|
|
95
|
+
void split(vector<string>& ss, const char* s)
|
|
96
|
+
{
|
|
97
|
+
const char* p = s;
|
|
98
|
+
const char* pp = strchr(p, _T(','));
|
|
99
|
+
while (pp)
|
|
100
|
+
{
|
|
101
|
+
string s = string(p, pp);
|
|
102
|
+
ss.push_back(s);
|
|
103
|
+
p = pp + 1;
|
|
104
|
+
pp = strchr(p, _T(','));
|
|
105
|
+
}
|
|
106
|
+
size_t len = strlen(p);
|
|
107
|
+
if (len)
|
|
108
|
+
ss.push_back(string(p, p + len));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
void disconnect()
|
|
112
|
+
{
|
|
113
|
+
if (g_mgr)
|
|
114
|
+
g_mgr->release();
|
|
115
|
+
if (g_db)
|
|
116
|
+
database::destroy(g_db);
|
|
117
|
+
g_mgr = NULL;
|
|
118
|
+
g_db = NULL;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
bool connect(const string& host)
|
|
122
|
+
{
|
|
123
|
+
char buf[1024];
|
|
124
|
+
const char* up="@";
|
|
125
|
+
const char* pp="?pwd=";
|
|
126
|
+
if (user == "") { up = ""; pp = "";}
|
|
127
|
+
|
|
128
|
+
sprintf_s(buf, 1024, "tdap://%s%s%s/%s%s", user.c_str(), up,
|
|
129
|
+
host.c_str(), pp, passwd.c_str());
|
|
130
|
+
#ifdef _UNICODE
|
|
131
|
+
_TCHAR bufw[1024];
|
|
132
|
+
MultiByteToWideChar(CP_UTF8, 0, buf, -1, bufw, 1024);
|
|
133
|
+
const _TCHAR* uri = bufw;
|
|
134
|
+
#else
|
|
135
|
+
const _TCHAR* uri = buf;
|
|
136
|
+
#endif
|
|
137
|
+
if (g_mgr->connect(uri))
|
|
138
|
+
return true;
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
inline const char* slaveHost()
|
|
143
|
+
{
|
|
144
|
+
return cache_slave.c_str();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
inline const char* masterHost()
|
|
148
|
+
{
|
|
149
|
+
return cache_master.c_str();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
inline bool registerHaNameResolver(HANAME_RESOLVER_PTR func)
|
|
153
|
+
{
|
|
154
|
+
return nsdatabase::registerHaNameResolver(func);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
bool checkSlaveStatus(const char* chnnel)
|
|
158
|
+
{
|
|
159
|
+
g_recs = g_mgr->slaveStatus(chnnel);
|
|
160
|
+
if (g_recs.size() > SLAVE_STATUS_SLAVE_SQL_RUNNING)
|
|
161
|
+
return (strcmp(g_recs[SLAVE_STATUS_SLAVE_SQL_RUNNING].name, "Yes") == 0) &&
|
|
162
|
+
(strcmp(g_recs[SLAVE_STATUS_SLAVE_IO_RUNNING].name, "Yes") == 0);
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
bool readReplMaster(const string& host)
|
|
167
|
+
{
|
|
168
|
+
if (connect(host))
|
|
169
|
+
{
|
|
170
|
+
/* read channel with wait lock in the server 60 second max */
|
|
171
|
+
g_recs = g_mgr->channels(true /*withLock*/);
|
|
172
|
+
if (g_recs.size())
|
|
173
|
+
{
|
|
174
|
+
char channle[MAX_PATH];
|
|
175
|
+
g_recs[0].value(channle, MAX_PATH);
|
|
176
|
+
g_recs = g_mgr->statusvars();
|
|
177
|
+
int ha = HA_ROLE_SLAVE;
|
|
178
|
+
if (g_recs.size() > TD_SVAR_HA)
|
|
179
|
+
ha = (int)g_recs[TD_SVAR_HA].longValue;
|
|
180
|
+
if ((ha & (HA_ROLE_MASTER | HA_ROLE_NONE)) == HA_ROLE_SLAVE)
|
|
181
|
+
{
|
|
182
|
+
if (checkSlaveStatus(channle))
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
}else
|
|
186
|
+
{
|
|
187
|
+
g_recs = g_mgr->statusvars();
|
|
188
|
+
int ha = HA_ROLE_MASTER;
|
|
189
|
+
if (g_recs.size() > TD_SVAR_HA)
|
|
190
|
+
ha = (int)g_recs[TD_SVAR_HA].longValue;
|
|
191
|
+
if ((ha & HA_ROLE_MASTER) == HA_ROLE_MASTER)
|
|
192
|
+
cache_master = host;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (g_mgr)
|
|
196
|
+
{
|
|
197
|
+
g_mgr->release();
|
|
198
|
+
g_db->close();
|
|
199
|
+
g_mgr = connMgr::create(g_db);
|
|
200
|
+
}
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
bool selectSlave()
|
|
205
|
+
{
|
|
206
|
+
// First try, specified slave server
|
|
207
|
+
g_slaveIndex = g_slaveNum;
|
|
208
|
+
if (g_slaveNum < (short)slaveHosts.size() && readReplMaster(slaveHosts[g_slaveNum]))
|
|
209
|
+
return true;
|
|
210
|
+
// After, each slave of slave list
|
|
211
|
+
for (size_t i=0;i < slaveHosts.size(); ++i)
|
|
212
|
+
{
|
|
213
|
+
if ((short)i != g_slaveNum)
|
|
214
|
+
{
|
|
215
|
+
g_slaveIndex = (int)i;
|
|
216
|
+
if (readReplMaster(slaveHosts[i]))
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
g_mgr->release();
|
|
221
|
+
g_mgr = NULL;
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
char* getHostName(char* str)
|
|
226
|
+
{
|
|
227
|
+
char* p = strchr(str, '\t');
|
|
228
|
+
if (p)
|
|
229
|
+
*p = 0x00;
|
|
230
|
+
return str;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
int setSlaveHosts()
|
|
234
|
+
{
|
|
235
|
+
if (g_slaveIndex < (short)slaveHosts.size())
|
|
236
|
+
{
|
|
237
|
+
cache_slave = slaveHosts[g_slaveIndex];
|
|
238
|
+
return 0;
|
|
239
|
+
}
|
|
240
|
+
return THNR_SLAVE_HOSTS_NOT_FOUND;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
void addPort(short port)
|
|
244
|
+
{
|
|
245
|
+
for (size_t i=0;i<g_portMap.size();++i)
|
|
246
|
+
{
|
|
247
|
+
if (g_portMap[i].myPort == port)
|
|
248
|
+
{
|
|
249
|
+
char tmp[24];
|
|
250
|
+
_ltoa_s(g_portMap[i].tdPort, tmp, 24, 10);
|
|
251
|
+
cache_master += ":" + string(tmp);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
void setMasterHost()
|
|
258
|
+
{
|
|
259
|
+
char tmp[MAX_PATH];
|
|
260
|
+
cache_master = g_recs[SLAVE_STATUS_MASTER_HOST].value(tmp, MAX_PATH);
|
|
261
|
+
g_recs[SLAVE_STATUS_MASTER_PORT].value(tmp, MAX_PATH);
|
|
262
|
+
addPort((short)atol(tmp));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const char* logPath(char* buf)
|
|
266
|
+
{
|
|
267
|
+
#ifdef _WIN32
|
|
268
|
+
SHGetFolderPathA(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, buf);
|
|
269
|
+
strcat_s(buf, MAX_PATH, PSEPARATOR_A "BizStation");
|
|
270
|
+
_mkdir(buf);
|
|
271
|
+
strcat_s(buf, MAX_PATH, PSEPARATOR_A "Transactd");
|
|
272
|
+
_mkdir(buf);
|
|
273
|
+
#else
|
|
274
|
+
strcpy_s(buf, MAX_PATH, "/var/log");
|
|
275
|
+
#endif
|
|
276
|
+
strcat_s(buf, MAX_PATH, PSEPARATOR_A TD_CLINET_LOGNAME);
|
|
277
|
+
return buf;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
int callFailover()
|
|
281
|
+
{
|
|
282
|
+
const char* fmt = "haMgr%d -c failover -s %s -u %s -p %s %s %s >> %s";
|
|
283
|
+
char tmp[4096];
|
|
284
|
+
int cpu = sizeof(char*) == 8 ? 64 :32;
|
|
285
|
+
string slaves;
|
|
286
|
+
for (size_t i = 0; i < slaveHosts.size(); ++i)
|
|
287
|
+
slaves += slaveHosts[i] + ",";
|
|
288
|
+
if (slaves.size())
|
|
289
|
+
slaves.erase(slaves.end() - 1);
|
|
290
|
+
|
|
291
|
+
string portmap;
|
|
292
|
+
for (size_t i = 0; i < g_portMap.size(); ++i)
|
|
293
|
+
{
|
|
294
|
+
if (i == 0) portmap = "-a ";
|
|
295
|
+
sprintf_s(tmp, 4096, "%d:%d,", g_portMap[i].tdPort, g_portMap[i].myPort);
|
|
296
|
+
portmap += tmp;
|
|
297
|
+
}
|
|
298
|
+
if (portmap.size())
|
|
299
|
+
portmap.erase(portmap.end() - 1);
|
|
300
|
+
|
|
301
|
+
char buf[MAX_PATH];
|
|
302
|
+
logPath(buf);
|
|
303
|
+
|
|
304
|
+
sprintf_s(tmp, 4096, fmt, cpu, slaves.c_str(), user.c_str(), passwd.c_str(),
|
|
305
|
+
portmap.size() ? portmap.c_str() : "",
|
|
306
|
+
g_readonly_control ? "-R1": "", buf);
|
|
307
|
+
return system(tmp);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/* Read from the slave server's master */
|
|
311
|
+
int setHosts()
|
|
312
|
+
{
|
|
313
|
+
g_db = database::create();
|
|
314
|
+
g_mgr = connMgr::create(g_db);
|
|
315
|
+
cache_master = "-";
|
|
316
|
+
cache_slave = "-";
|
|
317
|
+
int ret = THNR_INVALID_HOSTS;
|
|
318
|
+
if (selectSlave())
|
|
319
|
+
{
|
|
320
|
+
setMasterHost();
|
|
321
|
+
disconnect();
|
|
322
|
+
ret = setSlaveHosts();
|
|
323
|
+
}else if (cache_master != "-")
|
|
324
|
+
ret = THNR_SLAVE_HOSTS_NOT_FOUND;
|
|
325
|
+
disconnect();
|
|
326
|
+
if (g_failover && !g_failoverError)
|
|
327
|
+
{
|
|
328
|
+
g_failover = false;
|
|
329
|
+
bool fa = cache_master == "-";
|
|
330
|
+
if(!fa)
|
|
331
|
+
{
|
|
332
|
+
g_db = database::create();
|
|
333
|
+
g_mgr = connMgr::create(g_db);
|
|
334
|
+
bool ret = connect(cache_master);
|
|
335
|
+
short stat = g_mgr->stat();
|
|
336
|
+
disconnect();
|
|
337
|
+
fa = (ret == false &&
|
|
338
|
+
stat >= ERROR_TD_HOSTNAME_NOT_FOUND &&
|
|
339
|
+
stat < ERROR_TD_NET_REMOTE_DISCONNECT);
|
|
340
|
+
|
|
341
|
+
}
|
|
342
|
+
if (fa)
|
|
343
|
+
{
|
|
344
|
+
g_failoverError = callFailover() != 0;
|
|
345
|
+
if (!g_failoverError)
|
|
346
|
+
return setHosts();
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return ret;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const char* masterHostInternal()
|
|
353
|
+
{
|
|
354
|
+
if (cache_master == "")
|
|
355
|
+
setHosts();
|
|
356
|
+
return cache_master.c_str();
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const char* slaveHostInternal()
|
|
360
|
+
{
|
|
361
|
+
if (cache_slave == "")
|
|
362
|
+
setHosts();
|
|
363
|
+
return cache_slave.c_str();
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
void updateRsolver()
|
|
367
|
+
{
|
|
368
|
+
boost::mutex::scoped_lock lck(g_nr_mutex);
|
|
369
|
+
if (g_failoverError) return;
|
|
370
|
+
nsdatabase::registerHaNameResolver(NULL);
|
|
371
|
+
g_failover = g_callFailover;
|
|
372
|
+
{
|
|
373
|
+
boost::scoped_ptr<boost::thread> t(new boost::thread(setHosts));
|
|
374
|
+
t->join();
|
|
375
|
+
}
|
|
376
|
+
g_failover = false;
|
|
377
|
+
registerHaNameResolver(hostNameResolver);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/* During the startResolver,resolver dose not work. */
|
|
381
|
+
int haNameResolver::start(const char* master, const char* slaves,
|
|
382
|
+
const char* slvHosts, short slaveNum,const char* userName,
|
|
383
|
+
const char* password, int option)
|
|
384
|
+
{
|
|
385
|
+
boost::mutex::scoped_lock lck(g_nr_mutex);
|
|
386
|
+
g_callFailover = (option & THNR_OPT_DISABLE_CALL_FAILOVER) == 0;
|
|
387
|
+
g_readonly_control = (option & THNR_OPT_FO_READONLY_CONTROL) == 0;
|
|
388
|
+
registerHaNameResolver(NULL);
|
|
389
|
+
masterRoleName = master;
|
|
390
|
+
split(slaveRoleNames, slaves);
|
|
391
|
+
split(slaveHosts, slvHosts);
|
|
392
|
+
g_slaveNum = slaveNum;
|
|
393
|
+
user = userName;
|
|
394
|
+
passwd = password;
|
|
395
|
+
int ret = setHosts();
|
|
396
|
+
if (ret <= THNR_SLAVE_HOSTS_NOT_FOUND)
|
|
397
|
+
{
|
|
398
|
+
if (!registerHaNameResolver(hostNameResolver))
|
|
399
|
+
ret = THNR_REGISTER_FUNC_ERROR;
|
|
400
|
+
if (ret != THNR_REGISTER_FUNC_ERROR &&
|
|
401
|
+
cache_slave == "-" &&
|
|
402
|
+
option & THNR_OPT_MASTER_CAN_CONCUR_SLAVE)
|
|
403
|
+
cache_slave = cache_master;
|
|
404
|
+
}
|
|
405
|
+
return ret;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
void haNameResolver::stop()
|
|
409
|
+
{
|
|
410
|
+
boost::mutex::scoped_lock lck(g_nr_mutex);
|
|
411
|
+
registerHaNameResolver(NULL);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
void haNameResolver::addPortMap(short mysqlPort, short transactdPort)
|
|
415
|
+
{
|
|
416
|
+
boost::mutex::scoped_lock lck(g_nr_mutex);
|
|
417
|
+
g_portMap.push_back(portMap(mysqlPort, transactdPort));
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
void haNameResolver::clearPortMap()
|
|
421
|
+
{
|
|
422
|
+
boost::mutex::scoped_lock lck(g_nr_mutex);
|
|
423
|
+
g_portMap.clear();
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const char* haNameResolver::master()
|
|
427
|
+
{
|
|
428
|
+
boost::mutex::scoped_lock lck(g_nr_mutex);
|
|
429
|
+
return masterHost();
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
const char* haNameResolver::slave()
|
|
433
|
+
{
|
|
434
|
+
boost::mutex::scoped_lock lck(g_nr_mutex);
|
|
435
|
+
return slaveHost();
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
const char* __STDCALL hostNameResolver(const char* vhost, const char* port, char* buf, unsigned int& opt)
|
|
439
|
+
{
|
|
440
|
+
if (opt & HST_OPTION_CLEAR_CACHE)
|
|
441
|
+
updateRsolver();
|
|
442
|
+
|
|
443
|
+
// Resolve a host name from a role name.
|
|
444
|
+
boost::mutex::scoped_lock lck(g_nr_mutex);
|
|
445
|
+
|
|
446
|
+
if (masterRoleName == vhost)
|
|
447
|
+
{
|
|
448
|
+
const char* p = masterHostInternal();
|
|
449
|
+
if (*p && (*p != '-'))
|
|
450
|
+
{
|
|
451
|
+
strcpy_s(buf, MAX_PATH, p);
|
|
452
|
+
opt |= HST_OPTION_ROLE_MASTER | CL_OPTION_CHECK_ROLE;
|
|
453
|
+
opt &= ~HST_OPTION_ROLE_SLAVE;
|
|
454
|
+
return buf;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
else
|
|
458
|
+
{
|
|
459
|
+
vector<string>::iterator it =
|
|
460
|
+
find(slaveRoleNames.begin(), slaveRoleNames.end(), vhost);
|
|
461
|
+
if (it != slaveRoleNames.end())
|
|
462
|
+
{
|
|
463
|
+
const char* p = slaveHostInternal();
|
|
464
|
+
if (*p && (*p != '-'))
|
|
465
|
+
{
|
|
466
|
+
strcpy_s(buf, MAX_PATH, p);
|
|
467
|
+
opt |= HST_OPTION_ROLE_SLAVE | CL_OPTION_CHECK_ROLE;
|
|
468
|
+
opt &= ~HST_OPTION_ROLE_MASTER;
|
|
469
|
+
return buf;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
strcpy_s(buf, MAX_PATH, vhost);
|
|
474
|
+
if (port[0])
|
|
475
|
+
{
|
|
476
|
+
strcat_s(buf, MAX_PATH, ":");
|
|
477
|
+
strcat_s(buf, MAX_PATH, port);
|
|
478
|
+
}
|
|
479
|
+
return buf;
|
|
480
|
+
}
|
|
481
|
+
} // namespace client
|
|
482
|
+
} // namespace tdap
|
|
483
|
+
} // namespace protocol
|
|
484
|
+
} // namespace db
|
|
485
|
+
} // namespace bzs
|
|
486
|
+
|