transactd 3.4.1 → 3.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CMakeLists.txt +2 -2
  3. data/bin/common/tdclc_32_3_5.dll +0 -0
  4. data/bin/common/tdclc_64_3_5.dll +0 -0
  5. data/build/common/options.cmake +12 -0
  6. data/build/common/transactd_cl_common.cmake +1 -0
  7. data/build/common/transactd_required.cmake +5 -0
  8. data/build/swig/ruby/tdclrb_wrap.cpp +1029 -130
  9. data/build/swig/tdcl.i +60 -5
  10. data/build/tdclc/CMakeLists.txt +30 -32
  11. data/build/tdclc/libtdclcm.map +1 -1
  12. data/build/tdclc/tdclc.cbproj +1 -1
  13. data/build/tdclc/tdclc.rc +4 -4
  14. data/build/tdclcpp/CMakeLists.txt +39 -48
  15. data/build/tdclcpp/tdclcpp.rc +4 -4
  16. data/build/tdclcpp/tdclcpp_bc.cbproj +4 -1
  17. data/build/tdclrb/CMakeLists.txt +5 -4
  18. data/build/tdclrb/tdclrb.rc +4 -4
  19. data/source/bzs/db/engine/mysql/database.cpp +45 -35
  20. data/source/bzs/db/engine/mysql/database.h +6 -8
  21. data/source/bzs/db/engine/mysql/dbManager.cpp +11 -0
  22. data/source/bzs/db/engine/mysql/dbManager.h +1 -0
  23. data/source/bzs/db/engine/mysql/ha.cpp +174 -0
  24. data/source/bzs/db/engine/mysql/ha.h +50 -0
  25. data/source/bzs/db/engine/mysql/mysqlInternal.h +18 -1
  26. data/source/bzs/db/engine/mysql/mysqlProtocol.cpp +222 -9
  27. data/source/bzs/db/engine/mysql/mysqlProtocol.h +5 -0
  28. data/source/bzs/db/protocol/tdap/client/client.cpp +23 -9
  29. data/source/bzs/db/protocol/tdap/client/client.h +125 -94
  30. data/source/bzs/db/protocol/tdap/client/connMgr.cpp +139 -30
  31. data/source/bzs/db/protocol/tdap/client/connMgr.h +40 -8
  32. data/source/bzs/db/protocol/tdap/client/database.cpp +17 -17
  33. data/source/bzs/db/protocol/tdap/client/database.h +15 -0
  34. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +10 -4
  35. data/source/bzs/db/protocol/tdap/client/haNameResolver.cpp +486 -0
  36. data/source/bzs/db/protocol/tdap/client/haNameResolver.h +74 -0
  37. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +102 -71
  38. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +15 -3
  39. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +2 -5
  40. data/source/bzs/db/protocol/tdap/client/nsTable.h +2 -1
  41. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +2 -2
  42. data/source/bzs/db/protocol/tdap/client/table.cpp +1 -2
  43. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +13 -0
  44. data/source/bzs/db/protocol/tdap/client/trnsctcl.def +1 -0
  45. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +9 -7
  46. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +2 -2
  47. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +328 -117
  48. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +7 -8
  49. data/source/bzs/db/protocol/tdap/tdapcapi.h +81 -41
  50. data/source/bzs/db/transactd/connManager.cpp +118 -93
  51. data/source/bzs/db/transactd/connManager.h +6 -1
  52. data/source/bzs/db/transactd/connectionRecord.h +27 -7
  53. data/source/bzs/db/transactd/transactd.cpp +24 -13
  54. data/source/bzs/env/crosscompile.h +2 -0
  55. data/source/bzs/netsvc/client/iconnection.h +2 -0
  56. data/source/bzs/netsvc/client/tcpClient.cpp +45 -14
  57. data/source/bzs/netsvc/client/tcpClient.h +21 -4
  58. data/source/bzs/netsvc/server/IAppModule.h +1 -0
  59. data/source/bzs/netsvc/server/serverCpt.cpp +1 -1
  60. data/source/bzs/netsvc/server/serverPipe.cpp +2 -0
  61. data/source/bzs/netsvc/server/serverTpool.cpp +3 -5
  62. data/source/bzs/test/tdclatl/test_v3.js +91 -3
  63. data/source/bzs/test/tdclphp/transactd_v3_Test.php +89 -3
  64. data/source/bzs/test/tdclrb/transactd_v3_spec.rb +69 -2
  65. data/source/bzs/test/trdclengn/testField.h +19 -1
  66. data/source/bzs/test/trdclengn/test_tdclcpp_ha.cpp +388 -0
  67. data/source/bzs/test/trdclengn/test_tdclcpp_v3.cpp +6 -1
  68. data/source/bzs/test/trdclengn/test_trdclengn.cpp +1 -0
  69. data/source/bzs/test/trdclengn/testbase.h +7 -1
  70. data/source/global/replication/haCommand.cpp +843 -0
  71. data/source/global/replication/haCommand.h +78 -0
  72. data/source/global/replication/haMgr.cpp +321 -0
  73. data/source/global/replication/replCommand.cpp +696 -0
  74. data/source/global/replication/replCommand.h +161 -0
  75. data/source/global/tdclatl/BinlogPos.cpp +10 -0
  76. data/source/global/tdclatl/BinlogPos.h +1 -0
  77. data/source/global/tdclatl/ConnMgr.cpp +89 -2
  78. data/source/global/tdclatl/ConnMgr.h +13 -1
  79. data/source/global/tdclatl/ConnRecord.cpp +8 -2
  80. data/source/global/tdclatl/ConnRecord.h +4 -3
  81. data/source/global/tdclatl/Database.cpp +13 -0
  82. data/source/global/tdclatl/Database.h +2 -0
  83. data/source/global/tdclatl/HaNameREsolver.cpp +54 -0
  84. data/source/global/tdclatl/HaNameREsolver.h +68 -0
  85. data/source/global/tdclatl/resource.h +0 -0
  86. data/source/global/tdclatl/tdclatl.idl +76 -5
  87. metadata +16 -6
  88. data/bin/common/tdclc_32_3_4.dll +0 -0
  89. data/bin/common/tdclc_64_3_4.dll +0 -0
  90. data/source/bzs/db/protocol/tdap/mysql/debuglog.cpp +0 -423
  91. data/source/bzs/db/protocol/tdap/mysql/debuglog.h +0 -116
@@ -0,0 +1,78 @@
1
+ #ifndef GLOBAL_REPLICATION_HACOMMANDH
2
+ #define GLOBAL_REPLICATION_HACOMMANDH
3
+ /*=================================================================
4
+ Copyright (C) 2016 BizStation Corp All rights reserved.
5
+
6
+ This program is free software; you can redistribute it and/or
7
+ modify it under the terms of the GNU General Public License
8
+ as published by the Free Software Foundation; either version 2
9
+ of the License, or (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with this program; if not, write to the Free Software
18
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19
+ 02111-1307, USA.
20
+ =================================================================*/
21
+ #include "replCommand.h"
22
+
23
+ #define OPT_SO_AUTO_SLVAE_LIST 1
24
+ #define OPT_FO_FAILOVER 2
25
+ #define OPT_DISABLE_OLD_TO_SLAVE 4
26
+ #define OPT_READONLY_CONTROL 8
27
+
28
+ struct failOverParam
29
+ {
30
+ mutable int option;
31
+ mutable std::_tstring slaves;
32
+ masterNode newMaster;
33
+ node master;
34
+ std::string portMap;
35
+ failOverParam() : option(0){}
36
+ bool isFailOver() const {return (option & OPT_FO_FAILOVER) != 0;}
37
+ bool isSwitchOver() const {return !isFailOver();}
38
+ bool isDisableOldMasterToSalve() const
39
+ {return (option & OPT_DISABLE_OLD_TO_SLAVE) != 0;}
40
+ };
41
+
42
+ class haNotify
43
+ {
44
+ public:
45
+ virtual ~haNotify() {};
46
+ virtual void onUpdateStaus(int status, const _TCHAR* msg) = 0;
47
+ virtual void setHostName(const _TCHAR* host) = 0;
48
+ };
49
+
50
+ #define HA_NF_ROLE_SLAVE 1
51
+ #define HA_NF_ROLE_MASTER 2
52
+ #define HA_NF_CANNELNAME 3
53
+ #define HA_SLAVE_START 4
54
+ #define HA_SLAVE_STOP 5
55
+ #define HA_SLAVE_STOP_ALL 6
56
+ #define HA_CHANGE_MASTER 7
57
+ #define HA_SWITCH_MASTER 8
58
+ #define HA_NF_WAIT_TRX_START 9
59
+ #define HA_NF_WAIT_TRX_COMP 10
60
+ #define HA_NF_SLAVE_LIST 11
61
+ #define HA_NF_PROMOTE_MASTER 12
62
+ #define HA_NF_PROMOTE_CHANNEL 13
63
+ #define HA_NF_WAIT_POS_START 14
64
+ #define HA_NF_WAIT_POS_COMP 15
65
+ #define HA_SET_READ_ONLY 16
66
+ #define HA_NF_MSG_OK 17
67
+ #define HA_NF_MSG_NG 18
68
+ #define HA_NF_DELAY 19
69
+ #define HA_NF_BLANK 20
70
+
71
+ void failOrver(const failOverParam& pm, haNotify* nf=NULL);
72
+ void switchOrver(const failOverParam& pm, haNotify* nf=NULL);
73
+ void demoteToSlave(const failOverParam& pm, haNotify* nf=NULL);
74
+ void setEnableFailOver(const failOverParam& pm, bool v);
75
+ void setServerRole(const failOverParam& pm, int v);
76
+ int healthCheck(const failOverParam& pm, haNotify* nf);
77
+
78
+ #endif // GLOBAL_REPLICATION_HACOMMANDH
@@ -0,0 +1,321 @@
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
+ #pragma hdrstop
20
+ #include <global/replication/haCommand.h>
21
+ #include <locale.h>
22
+ #include <iostream>
23
+ #include <vector>
24
+ #include <boost/program_options.hpp>
25
+ #include <bzs/rtl/stl_uty.h>
26
+ #include <bzs/db/protocol/tdap/btrDate.h>
27
+
28
+ #ifdef __BCPLUSPLUS__
29
+ #define BZS_LINK_BOOST_PROGRAM_OPTIONS
30
+ #include <bzs/env/boost_bcb_link.h>
31
+ #endif
32
+
33
+ using namespace bzs::db::protocol::tdap::client;
34
+ using namespace bzs::db::protocol::tdap;
35
+ using namespace boost::program_options;
36
+ using namespace std;
37
+
38
+ static const char* cmds = "switchover,failover,demote_to_slave,"
39
+ "set_failover_enable,set_server_role,health_check";
40
+ #define CMD_SWITCHOVER 0
41
+ #define CMD_FAILOVER 1
42
+ #define CMD_DEMOTE_TO_SLAVE 2
43
+ #define CMD_SET_FAILOVER_ENABLE 3
44
+ #define CMD_SET_SERVER_ROLE 4
45
+ #define CMD_HEALTH_CHECK 5
46
+
47
+
48
+ _tstring str_conv(std::string& v)
49
+ {
50
+ #ifdef _UNICODE
51
+ wchar_t wbuf[1024];
52
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, v.c_str(), -1, wbuf, 1024);
53
+ return wbuf;
54
+ #else
55
+ return v;
56
+ #endif //_UNICODE
57
+ }
58
+
59
+ class haMgrNotify : public haNotify
60
+ {
61
+ _tstring m_host;
62
+ public:
63
+ virtual ~haMgrNotify() {};
64
+ void onUpdateStaus(int status, const _TCHAR* msg)
65
+ {
66
+ const _TCHAR* p=_T("");
67
+ switch(status)
68
+ {
69
+ case HA_NF_ROLE_SLAVE: p = _T(": set role=SLAVE ");break;
70
+ case HA_NF_CANNELNAME: p = _T(": channel name=");break;
71
+ case HA_SLAVE_STOP_ALL: p = _T(": stop slave all ");break;
72
+ case HA_CHANGE_MASTER: p = _T(": change master to new master, pos=");break;
73
+ case HA_SWITCH_MASTER: p = _T(": change master to new master, pos=");break;
74
+ case HA_SLAVE_START: p = _T(": start slave ");break;
75
+ case HA_NF_WAIT_TRX_START: p = _T(": waiting for trx...");break;
76
+ case HA_NF_WAIT_TRX_COMP: p = _T(": wait is completed, pos=");break;
77
+ case HA_NF_SLAVE_LIST: p = _T("SLAVE_LIST=");break;
78
+ case HA_NF_PROMOTE_MASTER: p = _T(": promote to master ");break;
79
+ case HA_NF_PROMOTE_CHANNEL: p = _T(": channel name=");break;
80
+ case HA_NF_ROLE_MASTER: p = _T(": set role=MASTER ");break;
81
+ case HA_NF_WAIT_POS_START: p = _T(": waiting for until...");break;
82
+ case HA_NF_WAIT_POS_COMP: p = _T(": wait is completed, pos=");break;
83
+ case HA_SLAVE_STOP: p = _T(": stop slave ");break;
84
+ case HA_SET_READ_ONLY: p = _T(": set READ_ONLY=1");break;
85
+ case HA_NF_DELAY: p = _T(": SQL thread delay=");break;
86
+ case HA_NF_MSG_OK:
87
+ tcout << " " << m_host << _T(": ") << msg << _T(" OK!") << endl;
88
+ return;
89
+ case HA_NF_MSG_NG:
90
+ tcout << " " << m_host << _T(": ") << msg << _T(" NG!") << endl;
91
+ return;
92
+ }
93
+ tcout << " " << m_host << p << msg << endl;
94
+ }
95
+ void setHostName(const _TCHAR* host)
96
+ {
97
+ m_host = host;
98
+ }
99
+ };
100
+
101
+ int checkParam(failOverParam& pm, int cmd, int v)
102
+ {
103
+ if (cmd != CMD_FAILOVER)
104
+ {
105
+ if (pm.master.host == _T(""))
106
+ {
107
+ cout << "--cur_master is requered" << endl;
108
+ return 1;
109
+ }
110
+ }else
111
+ {
112
+ if (pm.slaves == _T(""))
113
+ {
114
+ cout << "--slaves is requered" << endl;
115
+ return 1;
116
+ }
117
+ }
118
+
119
+ if (cmd == CMD_SWITCHOVER || cmd == CMD_DEMOTE_TO_SLAVE)
120
+ {
121
+ if (pm.newMaster.host == _T(""))
122
+ {
123
+ cout << "--new_master is requered" << endl;
124
+ return 1;
125
+ }
126
+ if (pm.newMaster.repUser == "")
127
+ {
128
+ cout << "--repl_user is requered" << endl;
129
+ return 1;
130
+ }
131
+ if (pm.newMaster.repPasswd == "")
132
+ {
133
+ cout << "--repl_passwd is requered" << endl;
134
+ return 1;
135
+ }
136
+ }
137
+ return 0;
138
+ }
139
+
140
+ int getCommandLineOption(int argc, _TCHAR* argv[], failOverParam& pm, int& cmd, int& v)
141
+ {
142
+ std::string c, host, newMaster, user, pwd, slaves;
143
+ std::string port = "3306";
144
+ bool readonly = false;
145
+ bool disable_demote = false;
146
+ options_description opt("command line option");
147
+ opt.add_options()("command,c", value<std::string>(&c),
148
+ "command [switchover | failover | demote_to_slave | set_failover_enable | set_server_role | health_check]")
149
+ ("cur_master,o", value<std::string>(&host), "current master host name")
150
+ ("new_master,n", value<std::string>(&newMaster), "new master host name")
151
+ ("channel,C", value<std::string>(&pm.newMaster.channel), "new master channel name")
152
+ ("repl_port,P", value<std::string>(&pm.newMaster.repPort), "new master port")
153
+ ("repl_user,r", value<std::string>(&pm.newMaster.repUser), "new master repl user ")
154
+ ("repl_passwd,d", value<std::string>(&pm.newMaster.repPasswd), "new master repl password ")
155
+ ("repl_option,O", value<std::string>(&pm.newMaster.repOption), "option params for change master(ex: MASTER_CONNECT_RETRY=30)")
156
+ ("slaves,s", value<std::string>(&slaves), "slave list for failover")
157
+ ("portmap,a", value<std::string>(&pm.portMap), "port map ex:3307:8611")
158
+ ("value,v", value<int>(&v), "value (For set_failover_enable or set_server_role)")
159
+ ("username,u", value<std::string>(&user), "transactd username")
160
+ ("password,p", value<std::string>(&pwd), "transactd password")
161
+ ("readonly,R", value<bool>(&readonly), "0 | 1: When it is 1, the READONLY variable will be set ON to slaves and OFF to a master")
162
+ ("disable_demote,D", value<bool>(&disable_demote), "0 | 1: disable old master demote");
163
+ variables_map values;
164
+ store(parse_command_line(argc, argv, opt), values);
165
+ notify(values);
166
+ if (!values.count("command"))
167
+ {
168
+ cout << opt << endl;
169
+ return 1;
170
+ }
171
+ vector<string> cmdList;
172
+ split(cmdList, cmds, ",");
173
+ vector<string>::iterator it = find(cmdList.begin(), cmdList.end(), c);
174
+ if (it== cmdList.end())
175
+ {
176
+ cout << opt << endl;
177
+ return 1;
178
+ }
179
+ cmd = (int)(it - cmdList.begin());
180
+ if ((cmd == CMD_SET_SERVER_ROLE || cmd == CMD_SET_FAILOVER_ENABLE) &&
181
+ !values.count("value"))
182
+ {
183
+ cout << opt << endl;
184
+ return 1;
185
+ }
186
+ pm.newMaster.host = str_conv(newMaster);
187
+ pm.master.host = str_conv(host);
188
+ pm.master.user = str_conv(user);
189
+ pm.master.passwd = str_conv(pwd);
190
+ pm.slaves = str_conv(slaves);
191
+ if (readonly) pm.option |= OPT_READONLY_CONTROL;
192
+ if (disable_demote) pm.option |= OPT_DISABLE_OLD_TO_SLAVE;
193
+ return checkParam(pm, cmd, v);
194
+ }
195
+
196
+ void printDateTime()
197
+ {
198
+ btrDateTime bt;
199
+ char tmp[256];
200
+ bt.time.i = getNowTime();
201
+ bt.date.i = getNowDate();
202
+ btrstoa(bt, tmp, true);
203
+ cout << tmp;
204
+ }
205
+
206
+ void printMessage(const char* msg, const char* msg2="")
207
+ {
208
+ printDateTime();
209
+ cout << " " << msg << msg2 << endl;
210
+ }
211
+
212
+ #ifdef _UNICODE
213
+ void printMessage(const wchar_t* msg, const wchar_t* msg2=_T(""))
214
+ {
215
+ printDateTime();
216
+ tcout << " " << msg << msg2 << endl;
217
+ }
218
+ #endif
219
+
220
+ /* Command line paramater
221
+ command line option:
222
+ -c [ --command ] command [switchover | failover | demote_to_slave | set_failover_enable | set_server_role | health_check]
223
+ -o [ --cur_master ] current master host name
224
+ -n [ --new_master ] new master host name
225
+ -C [ --channel ] new master channel name
226
+ -P [ --repl_port ] new master port
227
+ -r [ --repl_user ] new master repl user
228
+ -d [ --repl_passwd ] new master repl password
229
+ -O [ --repl_option ] option params for change master(ex:MASTER_CONNECT_RETRY=30)
230
+ -s [ --slaves ] slave list for failover
231
+ -a [ --portmap ] port map ex:3307:8611
232
+ -v [ --value ] value (For set_failover_enable or set_server_role)
233
+ -u [ --username ] transactd username
234
+ -p [ --password ] transactd password
235
+ -R [ --readonly ] 0 | 1: When it is 1, the READONLY variable will be set ON to slaves and OFF to a master
236
+ -D [ --disable_demote ] 0 | 1: disable old master demote
237
+
238
+ example:
239
+ haMgr64 -c switchover -o localhost -n localhost:8611 -P 3307 -r replication_user -d xxxx -u root -p xxxx
240
+
241
+ haMgr64 -c failover -s localhost:8611,localhost:8612 -a 8610:3306,8611:3307,8612:3308
242
+ -u root -p
243
+
244
+ haMgr64 -c demote_to_slave -o localhost -n localhost:8611 -P 3307 -r replication_user -d xxxx
245
+ -d abcd -u root -p
246
+
247
+ haMgr64 -c set_failover_enable -v 1 -o localhost -u root -p
248
+
249
+ haMgr64 -c set_server_role -o localhost -v 1 -u root -p
250
+
251
+ haMgr64 -c health_check -o localhost -s localhost:8611,localhost:8612 -u root -p
252
+
253
+ */
254
+
255
+ #pragma argsused
256
+ int _tmain(int argc, _TCHAR* argv[])
257
+ {
258
+ #ifdef _WIN32
259
+ // set locale to current user locale.
260
+ std::locale::global(std::locale(""));
261
+ #endif
262
+ int ret = 1;
263
+ try
264
+ {
265
+ failOverParam pm;
266
+ int cmd = 0;
267
+ int v = 0;
268
+ ret = getCommandLineOption(argc, argv, pm, cmd, v);
269
+ if (ret == 0)
270
+ {
271
+ haMgrNotify nf;
272
+ switch (cmd)
273
+ {
274
+ case CMD_SWITCHOVER:
275
+ pm.option |= OPT_SO_AUTO_SLVAE_LIST;
276
+ printMessage("Starting switch over...");
277
+ switchOrver(pm, &nf);
278
+ break;
279
+ case CMD_FAILOVER:
280
+ printMessage("Starting fail over...");
281
+ failOrver(pm, &nf);
282
+ break;
283
+ case CMD_DEMOTE_TO_SLAVE:
284
+ printMessage("Starting demote to slave...");
285
+ demoteToSlave(pm, &nf);
286
+ break;
287
+ case CMD_SET_FAILOVER_ENABLE:
288
+ pm.option |= OPT_SO_AUTO_SLVAE_LIST;
289
+ setEnableFailOver(pm, v == 1);
290
+ break;
291
+ case CMD_SET_SERVER_ROLE:
292
+ setServerRole(pm, v);
293
+ break;
294
+ case CMD_HEALTH_CHECK:
295
+ printMessage("Starting health check...");
296
+ int errors = healthCheck(pm, &nf);
297
+ char tmp[256];
298
+ if (errors)
299
+ sprintf_s(tmp, 256, "%d errors detected.", errors);
300
+ else
301
+ sprintf_s(tmp, 256, "No errors detected.");
302
+ cout << endl << " *** " << tmp << endl << endl;
303
+ ret = errors;
304
+ break;
305
+ }
306
+ printMessage("Done!");
307
+ }
308
+ }
309
+ catch (bzs::rtl::exception& e)
310
+ {
311
+ printMessage(_T("Error! "), getMsg(e)->c_str());
312
+ ret = 1;
313
+ }
314
+ catch (std::exception& e)
315
+ {
316
+ printMessage("Error! ", e.what());
317
+ ret = 1;
318
+ }
319
+ return ret;
320
+ }
321
+ //---------------------------------------------------------------------------
@@ -0,0 +1,696 @@
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
+ #pragma hdrstop
20
+ #include "replCommand.h"
21
+ #pragma package(smart_init)
22
+ using namespace std;
23
+ using namespace bzs::db::protocol::tdap;
24
+ using namespace bzs::db::protocol::tdap::client;
25
+
26
+ #define ER_BAD_SLAVE 26200
27
+ #define WARN_NO_MASTER_INF 26617
28
+ #define ER_UNTIL_REQUIRES_USING_GTID 26949
29
+ #define ER_SLAVE_CHANNEL_DOES_NOT_EXIST 28074
30
+
31
+
32
+ connectParams node::cp(int opt)
33
+ {
34
+ bool nodb = (opt & CP_NO_DB) != 0;
35
+ bool noschem = nodb || ((opt & CP_NO_SCHEMA) != 0);
36
+ connectParams cp1(_T("tdap"),
37
+ host.c_str(),
38
+ nodb ? _T("") : db.c_str(),
39
+ noschem ? _T("") : schema.c_str(),
40
+ user.c_str(), passwd.c_str());
41
+ return cp1;
42
+ }
43
+
44
+ void node::setOption(int op, bool enable)
45
+ {
46
+ if (enable)
47
+ options |= op;
48
+ else
49
+ options &= ~op;
50
+ }
51
+
52
+ //------------------------------------------------------------------------------
53
+ struct replImpl
54
+ {
55
+ replicationParam& pm;
56
+
57
+ replImpl(replicationParam& p) : pm(p){}
58
+
59
+ virtual bool ignoreError(short stat) { return false;}
60
+
61
+ virtual void setSlaveSkipError(database_ptr db, const char* /*gtid*/)
62
+ {
63
+ execSql(db, "set global sql_slave_skip_counter=1");
64
+ }
65
+
66
+ virtual void setGtidSlavePos(database_ptr db, const binlogPos& bpos,
67
+ connMgr* mgr){}
68
+
69
+ virtual string stopSlaveSql() {return "stop slave";}
70
+
71
+ virtual string stopAllSlaveSql() {return "stop slave";}
72
+
73
+ virtual string startSlaveSql() {return "start slave";}
74
+
75
+ virtual string startAllSlaveSql() {return "start slave";}
76
+
77
+ virtual string resetSlaveSql() {return "reset slave";}
78
+
79
+ virtual string resetSlaveAllSql() {return "reset slave all";}
80
+
81
+ virtual string resetMasterSql() {return "reset master";}
82
+
83
+ virtual string changeMasterSql(const binlogPos& bpos, connMgr* /*mgr*/)
84
+ {
85
+ char tmp[128];
86
+ _i64toa_s(bpos.pos, tmp, 128, 10);
87
+ return changeMasterBaseSql()
88
+ + ", master_log_file='" + string(bpos.filename)
89
+ + "', master_log_pos=" + tmp;
90
+ }
91
+
92
+ virtual string switchMasterSql(replSlave::autoPosType)
93
+ {
94
+ THROW_BZS_ERROR_WITH_MSG(_T("No support switchMaster at this replication type."));
95
+ }
96
+
97
+ virtual string startSlaveUntilSql(const binlogPos& bpos)
98
+ {
99
+ char buf[128];
100
+ _i64toa_s(bpos.pos, buf, 128, 10);
101
+ return "start slave until master_log_file='"
102
+ + string(bpos.filename) + "', master_log_pos="
103
+ + string(buf);
104
+ }
105
+ protected:
106
+ std::vector<string> getGtids(char* str)
107
+ {
108
+ std::vector<string> gtids;
109
+ char* en = str + strlen(str);;
110
+ char* st = str;
111
+ while (st < en)
112
+ {
113
+ char* p = strchr(st, ',');
114
+ if (p) *p = 0x00;
115
+ gtids.push_back(st);
116
+ st = p ? p + 1 : en;
117
+ if (*st == '\n') ++st;
118
+ }
119
+ return gtids;
120
+ }
121
+
122
+ string changeMasterBaseSql()
123
+ {
124
+ masterNode& mn = pm.master;
125
+ string host = toUtf8(mn.host);
126
+ // remove port number
127
+ size_t pos = host.find(":");
128
+ if (pos != std::string::npos)
129
+ host.erase(host.begin() + pos, host.end());
130
+ string s = "change master to master_host='" + host + "'";
131
+ if (mn.repPort != "")
132
+ s += ", master_port=" + mn.repPort;
133
+ if (mn.repUser != "")
134
+ {
135
+ s += ", master_user='" + mn.repUser + "'";
136
+ s += ", master_password='" + mn.repPasswd + "'";
137
+ }
138
+ if (mn.repOption != "")
139
+ s += "," + mn.repOption;
140
+ return s;
141
+ }
142
+ };
143
+
144
+ struct replImplMaria : public replImpl
145
+ {
146
+ replImplMaria(database_ptr db, replicationParam& p) : replImpl(p)
147
+ {
148
+ if (pm.master.channel != "")
149
+ {
150
+ char tmp[256];
151
+ sprintf_s(tmp, 256, "set session default_master_connection='%s'",
152
+ pm.master.channel.c_str());
153
+ execSql(db, tmp);
154
+ }
155
+ }
156
+
157
+ bool ignoreError(short stat) { return stat == WARN_NO_MASTER_INF;}
158
+
159
+ string stopAllSlaveSql() {return "stop all slaves";}
160
+
161
+ string startAllSlaveSql() {return "start all slaves";}
162
+
163
+ string changeMasterSql(const binlogPos& bpos, connMgr* mgr)
164
+ {
165
+ if (pm.type == REP_TYPE_REGACY)
166
+ return replImpl::changeMasterSql(bpos, mgr);
167
+ return changeMasterBaseSql() + ", master_use_gtid=slave_pos";
168
+ }
169
+
170
+ string switchMasterSql(replSlave::autoPosType v)
171
+ {
172
+ if (v == replSlave::slave_pos)
173
+ return changeMasterBaseSql() + ", master_use_gtid=slave_pos";
174
+ else
175
+ return changeMasterBaseSql() + ", master_use_gtid=current_pos";
176
+ }
177
+
178
+ void setGtidSlavePos(database_ptr db, const binlogPos& bpos, connMgr* mgr)
179
+ {
180
+ if (pm.type == REP_TYPE_REGACY) return;
181
+ string gtid = getAllGtids(bpos, mgr);
182
+ string s = "set global gtid_slave_pos=\"" + gtid + "\"";
183
+ execSql(db, s.c_str());
184
+ }
185
+ private:
186
+ inline uint_td domainid(const char* gtid) {return strtoul(gtid, NULL, 10);}
187
+
188
+ string getAllGtids(const binlogPos& bpos, connMgr* mgr)
189
+ {
190
+ string gtid = bpos.gtid;
191
+ uint_td domain = domainid(gtid.c_str());
192
+ //const connMgr::records recs = mgr->channels();
193
+ connRecords_ptr recs_p = createConnRecords(mgr->channels());
194
+ const connMgr::records& recs = *recs_p.get();
195
+
196
+
197
+ validateStatus(mgr, _T("channels"));
198
+ if (recs.size())
199
+ {
200
+ const connMgr::records& recs2 = mgr->slaveStatus(recs[0].name);
201
+ validateStatus(mgr, _T("Gtids slaveStatus"));
202
+ if (recs2.size() > SLAVE_STATUS_MA_GTID_IO_POS)
203
+ {
204
+ char tmp[256];
205
+ recs2[SLAVE_STATUS_MA_GTID_IO_POS].value(tmp, 256);
206
+ std::vector<string> gtids = getGtids(tmp);
207
+
208
+ for (size_t i=0; i < gtids.size(); ++i)
209
+ {
210
+ if (domain != domainid(gtids[i].c_str()))
211
+ gtid += string(",") + gtids[i];
212
+ }
213
+ }
214
+ }
215
+ return gtid;
216
+ }
217
+ };
218
+
219
+ //------------------------------------------------------------------------------
220
+ struct replImplMy : public replImpl
221
+ {
222
+ replImplMy(replicationParam& p) : replImpl(p){}
223
+
224
+ void setSlaveSkipError(database_ptr db, const char* gtid)
225
+ {
226
+ char tmp[256] = "set gtid_next = \"";
227
+ strcat_s(tmp, 256, gtid);
228
+ strcat_s(tmp, 256, "\"");
229
+ execSql(db, tmp);
230
+ execSql(db, "start transaction");
231
+ execSql(db, "commit");
232
+ execSql(db, "set gtid_next = automatic");
233
+ }
234
+
235
+ string changeMasterSql(const binlogPos& bpos, connMgr* mgr)
236
+ {
237
+ if (pm.type == REP_TYPE_REGACY)
238
+ return replImpl::changeMasterSql(bpos, mgr);
239
+ return changeMasterBaseSql() + ", master_auto_position=1";
240
+ }
241
+
242
+ string switchMasterSql(replSlave::autoPosType /*v*/)
243
+ {
244
+ return changeMasterBaseSql() + ", master_auto_position=1";
245
+ }
246
+
247
+ void setGtidSlavePos(database_ptr db, const binlogPos& bpos, connMgr* mgr)
248
+ {
249
+ if (pm.type == REP_TYPE_REGACY || !pm.slave.option(OPT_RESET_MASTER))
250
+ return;
251
+ string s = "set global gtid_purged=\"" + gtidset(bpos, mgr) + "\"";
252
+ execSql(db, "reset master");
253
+ execSql(db, s.c_str());
254
+ }
255
+ private:
256
+ virtual string gtidset(const binlogPos& bpos, connMgr* /*mgr*/)
257
+ {
258
+ return bpos.gtid;
259
+ }
260
+ };
261
+
262
+ //------------------------------------------------------------------------------
263
+ struct replImplMy57 : public replImplMy
264
+ {
265
+ replImplMy57(replicationParam& p) : replImplMy(p){}
266
+
267
+ bool ignoreError(short stat)
268
+ {
269
+ return (stat == ER_SLAVE_CHANNEL_DOES_NOT_EXIST);
270
+ }
271
+
272
+ string stopSlaveSql() {return "stop slave" + channelSql();}
273
+
274
+ string startSlaveSql() {return "start slave" + channelSql();}
275
+
276
+ string resetSlaveSql() {return "reset slave" + channelSql();}
277
+
278
+ string resetSlaveAllSql() {return "reset slave all" + channelSql();}
279
+
280
+ string startSlaveUntilSql(const binlogPos& bpos)
281
+ {
282
+ return replImpl::startSlaveUntilSql(bpos) + channelSql();
283
+ }
284
+
285
+ string changeMasterSql(const binlogPos& bpos, connMgr* mgr)
286
+ {
287
+ return replImplMy::changeMasterSql(bpos, mgr) + channelSql();
288
+ }
289
+
290
+ string switchMasterSql(replSlave::autoPosType v)
291
+ {
292
+ return replImplMy::switchMasterSql(v) + channelSql();
293
+ }
294
+
295
+ private:
296
+ string channelSql() {return " for channel '" + pm.master.channel + "'";}
297
+
298
+ string uuid(string& gtid)
299
+ {
300
+ size_t pos = gtid.find(':');
301
+ if (pos != string::npos)
302
+ return gtid.substr(0, pos);
303
+ assert(0);
304
+ return "";
305
+ }
306
+
307
+ string gtidset(const binlogPos& bpos, connMgr* mgr)
308
+ { // all channels
309
+ char tmp[4096];
310
+ string gtid = bpos.gtid;
311
+ strcpy_s(tmp, 4096, gtid.c_str());
312
+ std::vector<string> gds = getGtids(tmp);
313
+ std::vector<string> uuids;
314
+ for (size_t i=0;i<gds.size(); ++i)
315
+ uuids.push_back(uuid(gds[i]));
316
+
317
+ //const connMgr::records recs = mgr->channels();
318
+ connRecords_ptr recs_p = createConnRecords(mgr->channels());
319
+ const connMgr::records& recs = *recs_p.get();
320
+
321
+
322
+ validateStatus(mgr, _T("channels"));
323
+ for (size_t i = 0; i < recs.size(); ++i)
324
+ {
325
+ if (pm.master.channel != recs[i].name)
326
+ {
327
+ const connMgr::records& recs2 = mgr->slaveStatus(recs[i].name);
328
+ validateStatus(mgr, _T("Gtids slaveStatus"));
329
+ if (recs2.size() > SLAVE_STATUS_EXECUTED_GTID_SET)
330
+ {
331
+ recs2[SLAVE_STATUS_EXECUTED_GTID_SET].value(tmp, 4096);
332
+ std::vector<string> gtids = getGtids(tmp);
333
+
334
+ for (size_t i=0; i < gtids.size(); ++i)
335
+ {
336
+ string uid = uuid(gtids[i]);
337
+ if (find(uuids.begin(), uuids.end(), uid) == uuids.end())
338
+ gtid += string(",") + gtids[i];
339
+ }
340
+ return gtid;
341
+ }
342
+ }
343
+ }
344
+ return gtid;
345
+ }
346
+ };
347
+
348
+ //------------------------------------------------------------------------------
349
+ // support functions
350
+ //------------------------------------------------------------------------------
351
+ bool isMySqlGtidMode(connMgr* mgr)
352
+ {
353
+ const connMgr::records& rec = mgr->extendedvars();
354
+ return (rec.size() && (rec[TD_EXTENDED_VAR_MYSQL_GTID_MODE].longValue != 0));
355
+ }
356
+
357
+ void notyfy(replicationNotify* nf, int v)
358
+ {
359
+ if (nf) nf->onUpdateStaus(v);
360
+ }
361
+
362
+ int resolv(replicationNotify* nf, int type, const connMgr::records& recs, int defValue)
363
+ {
364
+ if (nf)
365
+ defValue = nf->onResolvError(type, recs);
366
+ return defValue;
367
+ }
368
+
369
+ __int64 getSlaveIOPos(const connMgr::records& recs)
370
+ {
371
+ if (recs.size() > SLAVE_STATUS_READ_MASTER_LOG_POS)
372
+ return recs[SLAVE_STATUS_READ_MASTER_LOG_POS].longValue;
373
+ return 0;
374
+ }
375
+
376
+ std::string getSkipGtid(const connMgr::records& recs)
377
+ {
378
+ string s;
379
+ if (recs.size() <= SLAVE_STATUS_EXECUTED_GTID_SET)
380
+ return s;
381
+ const char* uuid = recs[SLAVE_STATUS_MASTER_UUID].name;
382
+ char buf[1024];
383
+ char* p = (char*)recs[SLAVE_STATUS_EXECUTED_GTID_SET].name;
384
+ if (recs[SLAVE_STATUS_EXECUTED_GTID_SET].type == 2)
385
+ p = (char*)recs[SLAVE_STATUS_EXECUTED_GTID_SET].longValue;
386
+
387
+ p = strstr(p, uuid);
388
+ if (!p)
389
+ { // the first transaction error
390
+ s = uuid;
391
+ return s + ":1";
392
+ }
393
+ strcpy_s(buf, MAX_PATH, p);
394
+ p = buf;
395
+ char* pp = strchr(p, ',');
396
+ if (pp) *pp = 0x00;
397
+ pp = strrchr(p, ':');
398
+ if (pp)
399
+ {
400
+ *pp = 0x00;
401
+ s = p;
402
+ s += ":";
403
+ p = pp+1;
404
+ pp = strchr(p, '-');
405
+ if (pp) p = pp +1;
406
+ unsigned __int64 v = _atoi64(p);
407
+ ++v;
408
+ _i64toa_s(v, buf, MAX_PATH, 10);
409
+ s += buf;
410
+ }
411
+ return s;
412
+ }
413
+
414
+ bool isGtidAutoPos(const connMgr::records& recs)
415
+ {
416
+ return recs[SLAVE_STATUS_AUTO_POSITION].longValue != 0;
417
+ }
418
+
419
+ __int64 getSlaveExecPos(const connMgr::records& recs)
420
+ {
421
+ if (recs.size() > SLAVE_STATUS_EXEC_MASTER_LOG_POS)
422
+ return recs[SLAVE_STATUS_EXEC_MASTER_LOG_POS].longValue;
423
+ return 0;
424
+ }
425
+
426
+ bool isPosBrokn(const connMgr::records& recs)
427
+ {
428
+ __int64 iop = getSlaveIOPos(recs);
429
+ __int64 exp = getSlaveExecPos(recs);
430
+ return exp > iop;
431
+ }
432
+
433
+ bool isSamePosAsSlaveExecPos(const connMgr::records& recs, binlogPos& bpos)
434
+ {
435
+ return (strcmp(recs[SLAVE_STATUS_MASTER_LOG_FILE].name, bpos.filename)) == 0 &&
436
+ (recs[SLAVE_STATUS_EXEC_MASTER_LOG_POS].longValue == bpos.pos);
437
+ }
438
+
439
+ bool isSlaveSqlRunning(const connMgr::records& recs)
440
+ {
441
+ return strcmp(recs[SLAVE_STATUS_SLAVE_SQL_RUNNING].name, "Yes") == 0;
442
+ }
443
+
444
+ bool isSlaveIoRunning(const connMgr::records& recs)
445
+ {
446
+ return strcmp(recs[SLAVE_STATUS_SLAVE_IO_RUNNING].name, "Yes") == 0;
447
+ }
448
+
449
+ int getSlaveIoErrno(const connMgr::records& recs)
450
+ {
451
+ if (recs.size() > SLAVE_STATUS_LAST_IO_ERRNO)
452
+ return (int)recs[SLAVE_STATUS_LAST_IO_ERRNO].longValue;
453
+ return 0;
454
+ }
455
+
456
+ bool replSlave::resolvSqlError(const connMgr::records& recs,
457
+ binlogPos& bpos, replicationNotify* nf)
458
+ {
459
+ int ret = resolv(nf, ERROR_SQL_THREAD, recs, RESOLV_RESULT_CANCEL);
460
+ if (RESOLV_RESULT_CANCEL == ret)
461
+ THROW_BZS_ERROR_WITH_MSG(
462
+ _T("SQL thread has error(s).\nPlease retry after remove error(s)."));
463
+ else if (RESOLV_RESULT_YES == ret)
464
+ {
465
+ skipLogEvent(getSkipGtid(recs).c_str());
466
+ startUntil(bpos);
467
+ return false;
468
+ }else
469
+ stopAndReset();
470
+ return true;
471
+ }
472
+
473
+ bool replSlave::resolvIOError(const connMgr::records& recs, replicationNotify* nf)
474
+ {
475
+ int ret = resolv(nf, ERROR_IO_THREAD, recs, RESOLV_RESULT_CANCEL);
476
+ if(RESOLV_RESULT_YES != ret)
477
+ THROW_BZS_ERROR_WITH_MSG(_T("IO thread has error(s).\nPlease retry after remove error(s)."));
478
+ stopAndReset();
479
+
480
+ return true;
481
+ }
482
+
483
+ bool replSlave::resolvBroknError(const connMgr::records& recs, replicationNotify* nf)
484
+ {
485
+ int ret = resolv(nf, ERROR_LOG_BROKN, recs, RESOLV_RESULT_CANCEL);
486
+ if(RESOLV_RESULT_YES !=ret)
487
+ THROW_BZS_ERROR_WITH_MSG(_T("Log position error.\nRebuild of replication is required."));
488
+ stopAndReset();
489
+ return true;
490
+ }
491
+
492
+ string toUtf8(const _tstring& s)
493
+ {
494
+ #ifdef _UNICODE
495
+ char tmp[MAX_PATH]={0};
496
+ WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, tmp, MAX_PATH, NULL, NULL);
497
+ return tmp;
498
+ #else
499
+ return s;
500
+ #endif
501
+ }
502
+
503
+ //------------------------------------------------------------------------------
504
+ // class replSlave
505
+ //------------------------------------------------------------------------------
506
+ replSlave::replSlave(database_ptr db, replicationParam& pm, connMgr* mgr)
507
+ : m_db(db), m_mgr(mgr), m_mysqlGtid(false)
508
+ {
509
+
510
+ if (pm.type == REP_TYPE_GTID_MA)
511
+ m_impl = new replImplMaria(db, pm); // mariadb gtid
512
+ else
513
+ {
514
+ btrVersions vers;
515
+ db->getBtrVersion(&vers);
516
+ validateStatus(db, _T("get slave version"));
517
+ btrVersion ver = vers.versions[VER_IDX_DB_SERVER];
518
+ if (ver.majorVersion == 5 && ver.minorVersion < 6)
519
+ m_impl = new replImpl(pm); // mysql maridb 5.5
520
+ else if (ver.isMariaDB())
521
+ m_impl = new replImplMaria(db, pm);// maridb 10.0 10.1
522
+ else
523
+ {
524
+ m_mysqlGtid = isMySqlGtidMode(mgr);
525
+ if (!m_mysqlGtid)
526
+ m_impl = new replImpl(pm); // 5.6 5.7 regacy
527
+ else if (ver.minorVersion > 6)
528
+ m_impl = new replImplMy57(pm);// 5.7 gtid
529
+ else
530
+ m_impl = new replImplMy(pm); // 5.6 gtid
531
+ }
532
+ }
533
+ }
534
+
535
+ replSlave::~replSlave()
536
+ {
537
+ delete m_impl;
538
+ }
539
+
540
+ void replSlave::validateError(const _TCHAR* msg)
541
+ {
542
+ if (m_db->stat() == 0 || m_impl->ignoreError(m_db->stat()))
543
+ return;
544
+ validateStatus(m_db, msg);
545
+ }
546
+
547
+ void replSlave::setSkipError(const char* gtid)
548
+ {
549
+ m_impl->setSlaveSkipError(m_db, gtid);
550
+ }
551
+
552
+ void replSlave::stop(bool all)
553
+ {
554
+ string s;
555
+ if (all)
556
+ s = m_impl->stopAllSlaveSql();
557
+ else
558
+ s = m_impl->stopSlaveSql();
559
+ m_db->execSql(s.c_str());
560
+ validateError(_T("stop slave"));
561
+ }
562
+
563
+ void replSlave::start(bool all)
564
+ {
565
+ if (all)
566
+ execSql(m_db, m_impl->startAllSlaveSql().c_str());
567
+ else
568
+ execSql(m_db, m_impl->startSlaveSql().c_str());
569
+ }
570
+
571
+ void replSlave::startNoThrow()
572
+ {
573
+ m_db->execSql(m_impl->startSlaveSql().c_str());
574
+ }
575
+
576
+ void replSlave::reset()
577
+ {
578
+ string s = m_impl->resetSlaveSql();
579
+ m_db->execSql(s.c_str());
580
+ validateError(_T("reset slave"));
581
+ }
582
+
583
+ void replSlave::resetAll()
584
+ {
585
+ string s = m_impl->resetSlaveAllSql();
586
+ m_db->execSql(s.c_str());
587
+ validateError(_T("reset slave all"));
588
+ }
589
+
590
+ bool replSlave::startUntil(binlogPos& bpos)
591
+ {
592
+ m_db->execSql(m_impl->startSlaveUntilSql(bpos).c_str());
593
+ if ((m_db->stat() == ER_BAD_SLAVE) ||
594
+ (m_impl->pm.type == REP_TYPE_GTID_MA &&
595
+ m_db->stat() == ER_UNTIL_REQUIRES_USING_GTID))
596
+ return false;
597
+ if (m_db->stat())
598
+ nstable::throwError(_T("start slave until"), m_db->stat());
599
+ return true;
600
+ }
601
+
602
+ void replSlave::changeMaster(const binlogPos* bpos)
603
+ {
604
+ m_impl->setGtidSlavePos(m_db, *bpos, m_mgr);
605
+ execSql(m_db, m_impl->changeMasterSql(*bpos, m_mgr).c_str());
606
+ }
607
+
608
+ void replSlave::switchMaster(autoPosType v)
609
+ {
610
+ execSql(m_db, m_impl->switchMasterSql(v).c_str());
611
+ }
612
+
613
+ void replSlave::resetMaster()
614
+ {
615
+ execSql(m_db, "reset master");
616
+ }
617
+
618
+ void replSlave::skipLogEvent(const char* gtid)
619
+ {
620
+ stop(one);
621
+ setSkipError(gtid);
622
+ }
623
+
624
+ void replSlave::stopAndReset()
625
+ {
626
+ stop(one);
627
+ reset();
628
+ }
629
+
630
+ const replicationParam& replSlave::params() const
631
+ {
632
+ return m_impl->pm;
633
+ }
634
+
635
+ bool replSlave::isSlaveSync(binlogPos& bpos, replicationNotify* nf)
636
+ {
637
+ while (1)
638
+ {
639
+ const connMgr::records& recs = m_mgr->slaveStatus(m_impl->pm.master.channel.c_str());
640
+ validateStatus(m_mgr, _T("slave status"));
641
+ /* In the case of first-time replication, size is zero. */
642
+ if (recs.size() == 0)
643
+ return true;
644
+ bool isIgnoreBrokn = isMysqlGtidMode() && isGtidAutoPos(recs);
645
+ if (!isIgnoreBrokn && isPosBrokn(recs))
646
+ {
647
+ if (resolvBroknError(recs, nf))
648
+ return true;
649
+ }
650
+ if (isSamePosAsSlaveExecPos(recs, bpos))
651
+ return true;
652
+
653
+ if ((isSlaveIoRunning(recs) == false) && getSlaveIoErrno(recs))
654
+ {
655
+ if (resolvIOError(recs, nf))
656
+ return true;
657
+ }
658
+ else if (isSlaveSqlRunning(recs) == false)
659
+ {
660
+ if (resolvSqlError(recs, bpos, nf))
661
+ return true;
662
+ }
663
+ else
664
+ break;
665
+ Sleep(10);
666
+ }
667
+ return false;
668
+ }
669
+
670
+ void replSlave::waitForSlaveSync(binlogPos& bpos, int waitTime, replicationNotify* nf)
671
+ {
672
+ Sleep(100);
673
+ bool slaveSync = false;
674
+ int n = waitTime * 100;
675
+ for (int nn = 0;nn < 10; ++nn)
676
+ {
677
+ if (isSlaveSync(bpos, nf))
678
+ {
679
+ slaveSync = true;
680
+ break;
681
+ }
682
+ for (int i= 0;i < n; ++i)
683
+ {
684
+ notyfy(nf, REP_NF_WAIT);
685
+ Sleep(10);
686
+ }
687
+ }
688
+ if (!slaveSync)
689
+ THROW_BZS_ERROR_WITH_MSG(
690
+ _T("The slave SQL thread could not be executed")
691
+ _T("until the target of the log position in time"));
692
+ }
693
+
694
+
695
+
696
+