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.
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
+