transactd 3.4.1 → 3.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|