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
@@ -920,16 +920,13 @@ void nstable::tdap(ushort_td op)
920
920
  Sleep(m_impl->nsdb->lockWaitTime());
921
921
  break;
922
922
  default:
923
- #ifdef TEST_RECONNECT
924
- if (canRecoverNetError(m_stat))
923
+ if (nsdatabase::enableAutoReconnect() && canRecoverNetError(m_stat))
925
924
  {
926
- m_impl->nsdb->reconnect();
927
- if (m_stat) return;
925
+ if (!m_impl->nsdb->reconnect()) return;
928
926
  m_stat = ERROR_TD_NET_TIMEOUT;
929
927
  LoopCount = -1;
930
928
  break;
931
929
  }
932
- #endif
933
930
  return;
934
931
  }
935
932
  } while ((m_stat != STATUS_SUCCESS) &&
@@ -23,6 +23,7 @@
23
23
  #include <bzs/db/protocol/tdap/tdapSchema.h>
24
24
  #include <bzs/rtl/exception.h>
25
25
  #include "export.h"
26
+ #include <limits.h>
26
27
 
27
28
  namespace bzs
28
29
  {
@@ -193,7 +194,7 @@ public:
193
194
  return retbuf;
194
195
  }
195
196
 
196
- void beginBulkInsert(int maxBuflen);
197
+ void beginBulkInsert(int maxBuflen=BULKBUFSIZE);
197
198
  void abortBulkInsert() { doAbortBulkInsert(); }
198
199
  inline ushort_td commitBulkInsert(bool autoCommit = false)
199
200
  {
@@ -324,7 +324,7 @@ std::string sqlBuilder::getFieldList(const tabledef* table, std::vector<std::str
324
324
  }else if (fd.type == ft_bit)
325
325
  {
326
326
  s += " NULL DEFAULT b'";
327
- char tmp[100] = {NULL};
327
+ char tmp[100] = {0};
328
328
  s += getBitDefalutValue(tmp, 100, (unsigned __int64)fd.defaultValue64());
329
329
  s += "'";
330
330
  }
@@ -369,7 +369,7 @@ std::string sqlBuilder::getFieldList(const tabledef* table, std::vector<std::str
369
369
  }else if (fd.type == ft_bit)
370
370
  {
371
371
  s += "DEFAULT b'";
372
- char tmp[100] = {NULL};
372
+ char tmp[100] = {0};
373
373
  s += getBitDefalutValue(tmp, 100, (unsigned __int64)fd.defaultValue());
374
374
  s += "'";
375
375
  }
@@ -631,7 +631,6 @@ uint_td table::doRecordCount(bool estimate, bool fromCurrent)
631
631
  uint_td result = 0;
632
632
  client::filter* filter = m_impl->filterPtr.get();
633
633
 
634
-
635
634
  if (filter)
636
635
  {
637
636
  struct smartChangePreparedId
@@ -1544,7 +1543,7 @@ void table::doInit(tabledef** Def, short fnum, bool /*regularDir*/, bool mysqlnu
1544
1543
 
1545
1544
  keylen_td table::writeKeyDataTo(uchar_td* to, int keySize)
1546
1545
  {
1547
- if ((*m_tableDef)->keyCount)
1546
+ if ((*m_tableDef)->keyCount && m_keynum >= 0)
1548
1547
  {
1549
1548
  keydef& keydef =
1550
1549
  (*m_tableDef)->keyDefs[(int)m_impl->keyNumIndex[(int)m_keynum]];
@@ -968,6 +968,19 @@ inline void convertTable(Database_Ptr db, const _TCHAR* name,
968
968
  convertTable(db, tablenum, func);
969
969
  }
970
970
 
971
+ template <class Database_Ptr>
972
+ void execSql(Database_Ptr db, const char* sql)
973
+ {
974
+ db->execSql(sql);
975
+ #ifdef _UNICODE
976
+ wchar_t buf[1024];
977
+ MultiByteToWideChar(CP_UTF8, 0, sql, -1, buf, 1024);
978
+ validateStatus(db, buf);
979
+ #else
980
+ validateStatus(db, sql);
981
+ #endif
982
+ }
983
+
971
984
  inline void insertTable(dbdef* def, short id, const _TCHAR* name,
972
985
  unsigned short charsetIndex)
973
986
  {
@@ -8,4 +8,5 @@ EXPORTS
8
8
  BTRCALLID32 @5
9
9
  BTRCALL32 @6
10
10
  BeginWinThreadPoolShutdown @7
11
+ RegisterHaNameResolver @8
11
12
 
@@ -469,14 +469,16 @@ short schemaBuilder::execute(database* db, table* mtb, bool nouseNullkey)
469
469
  std::string s = it->path().filename().string();
470
470
  if (isFrmFile(s))
471
471
  {
472
- filename_to_tablename(it->path().stem().string().c_str(), path,
473
- FN_REFLEN);
474
- table* tb = db->openTable(path, TD_OPEN_READONLY, NULL, "");
475
- if (!tb) break;
476
- if (!tb->isView())
472
+ enum legacy_db_type not_used;
473
+ frm_type_enum ftype = dd_frm_type(db->thd(), (char*)it->path().string().c_str(), &not_used);
474
+ if (ftype == FRMTYPE_TABLE)
475
+ {
476
+ filename_to_tablename(it->path().stem().string().c_str(), path,
477
+ FN_REFLEN);
478
+ table* tb = db->openTable(path, TD_OPEN_READONLY, NULL, "");
479
+ if (!tb) break;
477
480
  tables.push_back(tb);
478
- else
479
- db->closeTable(tb);
481
+ }
480
482
  }
481
483
  }
482
484
  }
@@ -889,8 +889,8 @@ public:
889
889
  }
890
890
  }
891
891
  }
892
-
893
- tb->indexInit();
892
+ if (tb->keyNum() >= 0)
893
+ tb->indexInit();
894
894
  tb->blobBuffer()->clear();
895
895
  tb->setBlobFieldCount(blobs);
896
896
  return 0;
@@ -23,6 +23,7 @@
23
23
  #include <bzs/db/engine/mysql/mysqlProtocol.h>
24
24
  #include <bzs/db/engine/mysql/errorMessage.h>
25
25
  #include <bzs/db/engine/mysql/mydebuglog.h>
26
+ #include <bzs/db/engine/mysql/ha.h>
26
27
  #include <bzs/netsvc/server/IAppModule.h> //lookup for result value
27
28
  #include <bzs/db/transactd/appModule.h>
28
29
  #include <bzs/rtl/stl_uty.h>
@@ -36,10 +37,12 @@
36
37
  #include <bzs/rtl/exception.h>
37
38
  #include <random>
38
39
 
39
-
40
40
  extern int getTransactdIsolation();
41
41
  extern unsigned int getTransactdLockWaitTimeout();
42
42
 
43
+ /* implemnts in transactd.cpp */
44
+ extern unsigned int g_tcpServerType;
45
+
43
46
  namespace bzs
44
47
  {
45
48
  namespace db
@@ -404,89 +407,90 @@ bool dbExecuter::connect(request& req)
404
407
  return ret;
405
408
  }
406
409
 
407
- inline bool dbExecuter::doCreateTable(request& req)
410
+ inline void dbExecuter::doCreateTable(request& req)
408
411
  {
409
- // if table name is mata table and database is nothing
410
- // then cretate database too.
411
412
  database* db;
412
- bool ret = getDatabaseWithAuth(req, &db);
413
- if (ret && req.result == 0)
413
+ if (!getDatabaseWithAuth(req, &db) || req.result)
414
414
  {
415
- std::string dbSqlname = getDatabaseName(req, FOR_SQL);
416
- std::string cmd;
417
- if (isMetaDb(req))
418
- { // for database operation
419
- if (((req.keyNum == CR_SUBOP_CREATE_DBONLY) || (req.keyNum == 0)) &&
420
- (db->existsDatabase() == false))
421
- {
422
- req.result = ddl_createDataBase(dbSqlname);
423
- if (req.result == ER_DB_CREATE_EXISTS + MYSQL_ERROR_OFFSET)
424
- req.result = 0;
425
- }
426
- else if (req.keyNum == CR_SUBOP_DROP)
427
- {
428
- if (req.result == 0)
429
- {
430
- std::string dbname = db->name();
431
- dbManager::releaseDatabase(req.cid);
432
- req.result = ddl_dropDataBase(dbname, dbSqlname, req.cid);
433
- if (ER_DB_DROP_EXISTS+ MYSQL_ERROR_OFFSET == req.result) req.result = 0;
434
- }
435
- return ret;
436
- }
415
+ req.result = ERROR_TD_INVALID_CLINETHOST;
416
+ return;
417
+ }
418
+
419
+ // if table name is mata table and database is nothing
420
+ // then cretate database too.
421
+ std::string dbSqlname = getDatabaseName(req, FOR_SQL);
422
+ std::string cmd;
423
+ if (isMetaDb(req))
424
+ { // for database operation
425
+ if (((req.keyNum == CR_SUBOP_CREATE_DBONLY) || (req.keyNum == 0)) &&
426
+ (db->existsDatabase() == false))
427
+ {
428
+ req.result = ddl_createDataBase(dbSqlname);
429
+ if (req.result == ER_DB_CREATE_EXISTS + MYSQL_ERROR_OFFSET)
430
+ req.result = 0;
437
431
  }
438
- if (req.result == 0)
439
- { // table operation
440
- std::string tableSqlName = getTableName(req, FOR_SQL);
441
- std::string tableName = getTableName(req);
442
- if (req.keyNum == CR_SUBOP_DROP) // -128 is delete
432
+ else if (req.keyNum == CR_SUBOP_DROP)
433
+ {
434
+ if (req.result == 0)
443
435
  {
444
- req.result = ddl_dropTable(db, tableName, dbSqlname,
445
- tableSqlName);
446
- if (req.result == ER_BAD_TABLE_ERROR + MYSQL_ERROR_OFFSET)
447
- req.result = 0;
448
- }
449
- else if (req.keyNum == CR_SUBOP_RENAME)
450
- { // rename new is keybuf
451
- request reqold;
452
- reqold.keybuf = req.data;
453
- reqold.keylen = *req.datalen;
454
- req.result = ddl_renameTable(
455
- db, getTableName(reqold), /*oldname*/
456
- dbSqlname, getTableName(reqold, FOR_SQL), /*oldname*/
457
- tableSqlName /*newName*/);
436
+ std::string dbname = db->name();
437
+ dbManager::releaseDatabase(req.cid);
438
+ req.result = ddl_dropDataBase(dbname, dbSqlname, req.cid);
439
+ if (ER_DB_DROP_EXISTS+ MYSQL_ERROR_OFFSET == req.result) req.result = 0;
458
440
  }
459
- else if (req.keyNum == CR_SUBOP_SWAPNAME)
460
- { // swap name name2 = keybuf
461
- request reqold;
462
- reqold.keybuf = req.data;
463
- reqold.keylen = *req.datalen;
464
- req.result = ddl_replaceTable(
465
- db, getTableName(reqold), /*oldname*/
466
- tableName, /*newName*/
467
- dbSqlname, getTableName(reqold, FOR_SQL), /*oldname*/
468
- tableSqlName /*newName*/);
469
- }
470
- else if (req.keyNum != CR_SUBOP_CREATE_DBONLY)
471
- { // create
472
- if (req.data == NULL)
473
- req.result = 1;
474
- else
475
- { //-1 is overwrite
476
- if (req.keyNum == CR_SUB_FLAG_EXISTCHECK && tableName.size())
477
- {
478
- req.result = ddl_dropTable(db, tableName, dbSqlname,
479
- tableSqlName);
480
- if (req.result == ER_BAD_TABLE_ERROR + MYSQL_ERROR_OFFSET)
481
- req.result = 0;
482
- }
483
- if (req.result == 0)
484
- req.result = ddl_createTable(db, makeSQLcreateTable(req).c_str());
441
+ return;
442
+ }
443
+ }
444
+ if (req.result == 0)
445
+ { // table operation
446
+ std::string tableSqlName = getTableName(req, FOR_SQL);
447
+ std::string tableName = getTableName(req);
448
+ if (req.keyNum == CR_SUBOP_DROP) // -128 is delete
449
+ {
450
+ req.result = ddl_dropTable(db, tableName, dbSqlname,
451
+ tableSqlName);
452
+ if (req.result == ER_BAD_TABLE_ERROR + MYSQL_ERROR_OFFSET)
453
+ req.result = 0;
454
+ }
455
+ else if (req.keyNum == CR_SUBOP_RENAME)
456
+ { // rename new is keybuf
457
+ request reqold;
458
+ reqold.keybuf = req.data;
459
+ reqold.keylen = *req.datalen;
460
+ req.result = ddl_renameTable(
461
+ db, getTableName(reqold), /*oldname*/
462
+ dbSqlname, getTableName(reqold, FOR_SQL), /*oldname*/
463
+ tableSqlName /*newName*/);
464
+ }
465
+ else if (req.keyNum == CR_SUBOP_SWAPNAME)
466
+ { // swap name name2 = keybuf
467
+ request reqold;
468
+ reqold.keybuf = req.data;
469
+ reqold.keylen = *req.datalen;
470
+ req.result = ddl_replaceTable(
471
+ db, getTableName(reqold), /*oldname*/
472
+ tableName, /*newName*/
473
+ dbSqlname, getTableName(reqold, FOR_SQL), /*oldname*/
474
+ tableSqlName /*newName*/);
475
+ }
476
+ else if (req.keyNum != CR_SUBOP_CREATE_DBONLY)
477
+ { // create
478
+ if (req.data == NULL)
479
+ req.result = 1;
480
+ else
481
+ { //-1 is overwrite
482
+ if (req.keyNum == CR_SUB_FLAG_EXISTCHECK && tableName.size())
483
+ {
484
+ req.result = ddl_dropTable(db, tableName, dbSqlname,
485
+ tableSqlName);
486
+ if (req.result == ER_BAD_TABLE_ERROR + MYSQL_ERROR_OFFSET)
487
+ req.result = 0;
485
488
  }
489
+ if (req.result == 0)
490
+ req.result = ddl_createTable(db, makeSQLcreateTable(req).c_str());
486
491
  }
487
492
  }
488
493
  }
489
- return ret;
490
494
  }
491
495
 
492
496
  // open table and assign handle
@@ -684,16 +688,24 @@ inline int dbExecuter::doReadMultiWithSeek(request& req, int op,
684
688
  int ret = 1;
685
689
  m_tb = getTable(req.pbk->handle);
686
690
  char keynum = m_tb->keyNumByMakeOrder(req.keyNum);
687
- if (!m_tb->setKeyNum(keynum))
691
+ if (keynum == -1 && (op == TD_KEY_GE_NEXT_MULTI))
688
692
  {
689
- req.result = m_tb->stat();
690
- return ret;
693
+ m_tb->setNonKey(true);
694
+ op = TD_POS_NEXT_MULTI;
691
695
  }
696
+ else
697
+ {
698
+ if (!m_tb->setKeyNum(keynum))
699
+ {
700
+ req.result = m_tb->stat();
701
+ return ret;
702
+ }
692
703
 
693
- m_tb->setKeyValuesPacked((const uchar*)req.keybuf, req.keylen);
694
- m_tb->seekKey((op == TD_KEY_GE_NEXT_MULTI) ? HA_READ_KEY_OR_NEXT
695
- : HA_READ_KEY_OR_PREV,
696
- m_tb->keymap());
704
+ m_tb->setKeyValuesPacked((const uchar*)req.keybuf, req.keylen);
705
+ m_tb->seekKey((op == TD_KEY_GE_NEXT_MULTI) ? HA_READ_KEY_OR_NEXT
706
+ : HA_READ_KEY_OR_PREV,
707
+ m_tb->keymap());
708
+ }
697
709
 
698
710
  extRequest* ereq = (extRequest*)req.data;
699
711
  bool noBookmark = (ereq->itype & FILTER_CURRENT_TYPE_NOBOOKMARK) != 0;
@@ -713,7 +725,7 @@ inline int dbExecuter::doReadMultiWithSeek(request& req, int op,
713
725
  }
714
726
  else
715
727
  req.result = m_readHandler->begin(m_tb, ereq, true, nw,
716
- (op == TD_KEY_GE_NEXT_MULTI),
728
+ (op == TD_KEY_GE_NEXT_MULTI || op == HA_READ_KEY_OR_NEXT),
717
729
  noBookmark);
718
730
  if (req.result != 0)
719
731
  return ret;
@@ -723,6 +735,10 @@ inline int dbExecuter::doReadMultiWithSeek(request& req, int op,
723
735
  m_tb->getNextExt(m_readHandler, true, noBookmark);
724
736
  else if (op == TD_KEY_LE_PREV_MULTI)
725
737
  m_tb->getPrevExt(m_readHandler, true, noBookmark);
738
+ else if (op == TD_POS_NEXT_MULTI)
739
+ m_tb->stepNextExt(m_readHandler, false, noBookmark);
740
+ else if (op == TD_POS_PREV_MULTI)
741
+ m_tb->stepPrevExt(m_readHandler, false, noBookmark);
726
742
  }
727
743
  req.result = errorCodeSht(m_tb->stat());
728
744
  if (!m_tb->cursor())
@@ -1411,6 +1427,7 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
1411
1427
  case TD_RECONNECT:
1412
1428
  nw->resize(*req.datalen);
1413
1429
  resultBuffer = nw->ptr();
1430
+
1414
1431
  if (!doOpenTable(req, resultBuffer, true))
1415
1432
  {
1416
1433
  if (req.result == 0)
@@ -1421,8 +1438,12 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
1421
1438
  char* p = (char*)req.data;
1422
1439
  req.keyNum = *p;
1423
1440
  if (*(++p) == 0)
1424
- break;
1441
+ {
1442
+ req.paramMask = P_MASK_POSBLK;
1443
+ break; // No bookmark
1444
+ }
1425
1445
  req.data = ((char*)req.data) + 2;
1446
+
1426
1447
  if (m_tb) m_tb->unUse();
1427
1448
  }
1428
1449
  //fall through restore position
@@ -1557,8 +1578,7 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
1557
1578
  req.result = schemaBuilder().execute(getDatabaseCid(req.cid), m_tb, (req.keyNum==1));
1558
1579
  break;
1559
1580
  case TD_CREATETABLE:
1560
- if (!doCreateTable(req))
1561
- req.result = ERROR_TD_INVALID_CLINETHOST;
1581
+ doCreateTable(req);
1562
1582
  break;
1563
1583
  case TD_OPENTABLE:
1564
1584
  nw->resize(*req.datalen);
@@ -1801,6 +1821,11 @@ size_t dbExecuter::getAcceptMessage(char* message, size_t size)
1801
1821
 
1802
1822
  hst->transaction_isolation = (unsigned short)getTransactdIsolation();
1803
1823
  hst->lock_wait_timeout = getTransactdLockWaitTimeout();
1824
+ int role = getRole();
1825
+ if (role == HA_ROLE_MASTER)
1826
+ hst->options |= HST_OPTION_ROLE_MASTER;
1827
+ else if(role == HA_ROLE_SLAVE)
1828
+ hst->options |= HST_OPTION_ROLE_SLAVE;
1804
1829
  if (strcmp(g_auth_type, AUTH_TYPE_MYSQL_STR) == 0)
1805
1830
  {
1806
1831
  makeRandomKey(m_scramble, MYSQL_SCRAMBLE_LENGTH);
@@ -1817,6 +1842,31 @@ size_t dbExecuter::getAcceptMessage(char* message, size_t size)
1817
1842
  // ---------------------------------------------------------------------------
1818
1843
  // class connMgrExecuter
1819
1844
  // ---------------------------------------------------------------------------
1845
+ class safeLockReadChannels
1846
+ {
1847
+ connMgrExecuter* m_exec;
1848
+ bool m_locked;
1849
+ public:
1850
+ safeLockReadChannels(connMgrExecuter* exec) :
1851
+ m_exec(exec), m_locked(false){}
1852
+ bool lock()
1853
+ {
1854
+ int n = 0;
1855
+ while (!haLock())
1856
+ {
1857
+ Sleep(500);
1858
+ if (++n >= 120) return false;
1859
+ }
1860
+ m_locked = true;
1861
+ return m_locked;
1862
+ }
1863
+ int execute(char* buf, size_t& size)
1864
+ {
1865
+ return m_exec->channels(buf, size);
1866
+ }
1867
+ ~safeLockReadChannels() { if (m_locked) haUnlock();}
1868
+ };
1869
+
1820
1870
  connMgrExecuter::connMgrExecuter(request& req, unsigned __int64 parent, blobBuffer* bb)
1821
1871
  : m_req(req), m_modHandle(parent), m_blobBuffer(bb)
1822
1872
  {
@@ -1865,6 +1915,18 @@ int connMgrExecuter::systemVariables(char* buf, size_t& size)
1865
1915
  return serialize(m_req, buf, size, records, st.stat());
1866
1916
  }
1867
1917
 
1918
+ int connMgrExecuter::extendedVariables(netsvc::server::netWriter* nw)
1919
+ {
1920
+ connManager st(m_modHandle);
1921
+ const connection::records& records = st.extendedVariables(m_blobBuffer);
1922
+ int v = serialize(m_req, nw->ptr(), nw->datalen, records, st.stat(), m_blobBuffer);
1923
+ short dymmy = 0;
1924
+ if ((m_req.result == 0) && m_blobBuffer->fieldCount())
1925
+ nw->datalen = m_req.serializeBlobBody(m_blobBuffer, nw->ptr(), nw->datalen,
1926
+ FILE_MAP_SIZE, nw->optionalData(), dymmy);
1927
+ return v;
1928
+ }
1929
+
1868
1930
  int connMgrExecuter::statusVariables(char* buf, size_t& size)
1869
1931
  {
1870
1932
  connManager st(m_modHandle);
@@ -1889,14 +1951,16 @@ int connMgrExecuter::definedTables(char* buf, size_t& size)
1889
1951
  int connMgrExecuter::definedViews(char* buf, size_t& size)
1890
1952
  {
1891
1953
  connManager st(m_modHandle);
1892
- const connection::records& records = st.definedTables((const char*)m_req.keybuf, TABLE_TYPE_VIEW);
1954
+ const connection::records& records =
1955
+ st.definedTables((const char*)m_req.keybuf, TABLE_TYPE_VIEW);
1893
1956
  return serialize(m_req, buf, size, records, st.stat());
1894
1957
  }
1895
1958
 
1896
1959
  int connMgrExecuter::slaveStatus(netsvc::server::netWriter* nw)
1897
1960
  {
1898
1961
  connManager st(m_modHandle);
1899
- const connection::records& records = st.readSlaveStatus(m_blobBuffer);
1962
+ const connection::records& records =
1963
+ st.readSlaveStatus((const char*)m_req.keybuf, m_blobBuffer);
1900
1964
  int v = serialize(m_req, nw->ptr(), nw->datalen, records, st.stat(), m_blobBuffer);
1901
1965
  short dymmy = 0;
1902
1966
  if ((m_req.result == 0) && m_blobBuffer->fieldCount())
@@ -1905,6 +1969,25 @@ int connMgrExecuter::slaveStatus(netsvc::server::netWriter* nw)
1905
1969
  return v;
1906
1970
  }
1907
1971
 
1972
+ int connMgrExecuter::channels(char* buf, size_t& size)
1973
+ {
1974
+ connManager st(m_modHandle);
1975
+ const connection::records& records = st.channels();
1976
+ return serialize(m_req, buf, size, records, st.stat());
1977
+ }
1978
+
1979
+ int connMgrExecuter::slaveHosts(netsvc::server::netWriter* nw)
1980
+ {
1981
+ connManager st(m_modHandle);
1982
+ const connection::records& records = st.slaveHosts(m_blobBuffer);
1983
+ int v = serialize(m_req, nw->ptr(), nw->datalen, records, st.stat(), m_blobBuffer);
1984
+ short dymmy = 0;
1985
+ if ((m_req.result == 0) && m_blobBuffer->fieldCount())
1986
+ nw->datalen = m_req.serializeBlobBody(m_blobBuffer, nw->ptr(), nw->datalen,
1987
+ FILE_MAP_SIZE, nw->optionalData(), dymmy);
1988
+ return v;
1989
+ }
1990
+
1908
1991
  int connMgrExecuter::disconnectOne(char* buf, size_t& size)
1909
1992
  {
1910
1993
  connManager st(m_modHandle);
@@ -1924,44 +2007,158 @@ int connMgrExecuter::disconnectAll(char* buf, size_t& size)
1924
2007
  return EXECUTE_RESULT_SUCCESS;
1925
2008
  }
1926
2009
 
1927
- int connMgrExecuter::commandExec(netsvc::server::netWriter* nw)
2010
+ /* redefined. First defined at transactd.cpp */
2011
+ #define TCP_TPOOL_SERVER 2
2012
+ void haPrintMessage(module* mod, int op, bool retVal)
2013
+ {
2014
+ const char* p="";
2015
+ switch (op)
2016
+ {
2017
+ case TD_STSTCS_HA_LOCK: p = "HA_LOCK"; break;
2018
+ case TD_STSTCS_HA_UNLOCK: p = "HA_UNLOCK"; break;
2019
+ case TD_STSTCS_HA_SET_ROLEMASTER: p = "HA_SET_ROLEMASTER"; break;
2020
+ case TD_STSTCS_HA_SET_ROLENONE: p = "HA_SET_ROLENONE"; break;
2021
+ case TD_STSTCS_HA_SET_ROLESLAVE: p = "HA_SET_ROLESLAVE"; break;
2022
+ case TD_STSTCS_HA_SET_TRXBLOCK: p = "HA_SET_TRXBLOCK"; break;
2023
+ case TD_STSTCS_HA_SET_TRXNOBLOCK: p = "HA_SET_TRXNOBLOCK"; break;
2024
+ case TD_STSTCS_HA_ENABLE_FO: p = "HA_ENABLE_FO"; break;
2025
+ case TD_STSTCS_HA_DISBLE_FO: p = "HA_DISBLE_FO"; break;
2026
+ }
2027
+ if (retVal)
2028
+ sql_print_information("Transactd: %s by %s@%s", p, mod->user(), mod->host());
2029
+ else
2030
+ sql_print_error("Transactd: %s by %s@%s", p, mod->user(), mod->host());
2031
+ }
2032
+
2033
+ void connMgrExecuter::execHaCommand()
1928
2034
  {
1929
- if (m_req.keyNum == TD_STSTCS_DISCONNECT_ONE)
1930
- return disconnectOne(nw->ptr(), nw->datalen);
1931
- if (m_req.keyNum == TD_STSTCS_DISCONNECT_ALL)
1932
- return disconnectAll(nw->ptr(), nw->datalen);
2035
+ if (g_tcpServerType == TCP_TPOOL_SERVER)
2036
+ {
2037
+ m_req.reset();
2038
+ m_req.result = STATUS_NOSUPPORT_OP;
2039
+ return;
2040
+ }
2041
+ bool ret = true;
2042
+ switch ((int)m_req.keyNum)
2043
+ {
2044
+ case TD_STSTCS_HA_LOCK:
2045
+ ret = haLock();
2046
+ break;
2047
+ case TD_STSTCS_HA_UNLOCK:
2048
+ ret = haUnlock();
2049
+ break;
2050
+ case TD_STSTCS_HA_SET_ROLEMASTER:
2051
+ ret = setRole(HA_ROLE_MASTER);
2052
+ break;
2053
+ case TD_STSTCS_HA_SET_ROLENONE:
2054
+ ret = setRole(HA_ROLE_NONE);
2055
+ break;
2056
+ case TD_STSTCS_HA_SET_ROLESLAVE:
2057
+ ret = setRole(HA_ROLE_SLAVE);
2058
+ break;
2059
+ case TD_STSTCS_HA_SET_TRXBLOCK:
2060
+ case TD_STSTCS_HA_SET_TRXNOBLOCK:
2061
+ ret = setTrxBlock(m_req.keyNum == TD_STSTCS_HA_SET_TRXBLOCK);
2062
+ break;
2063
+ case TD_STSTCS_HA_ENABLE_FO:
2064
+ case TD_STSTCS_HA_DISBLE_FO:
2065
+ ret = setEnableFailover(m_req.keyNum == TD_STSTCS_HA_ENABLE_FO);
2066
+ break;
2067
+ }
2068
+ module* mod = dynamic_cast<module*>((module*)m_modHandle);
2069
+ assert(mod);
2070
+ haPrintMessage(mod, m_req.keyNum, ret);
2071
+ m_req.reset();
2072
+ if (ret == false)
2073
+ m_req.result = STATUS_LOCK_ERROR;
2074
+ }
1933
2075
 
1934
- if (*m_req.datalen == (uint_td)63976)
2076
+ int connMgrExecuter::commandExec(netsvc::server::netWriter* nw)
2077
+ {
2078
+ char_td op = m_req.keyNum;
2079
+ try
1935
2080
  {
1936
- switch (m_req.keyNum)
2081
+ if (op == TD_STSTCS_DISCONNECT_ONE)
2082
+ return disconnectOne(nw->ptr(), nw->datalen);
2083
+ else if (op == TD_STSTCS_DISCONNECT_ALL)
2084
+ return disconnectAll(nw->ptr(), nw->datalen);
2085
+ else if (op >= TD_STSTCS_HA_LOCK && op <= TD_STSTCS_HA_DISBLE_FO)
2086
+ execHaCommand();
2087
+ else if (*m_req.datalen == (uint_td)63976)
2088
+ {
2089
+ switch (op)
2090
+ {
2091
+ case TD_STSTCS_READ:
2092
+ return read(nw->ptr(), nw->datalen);
2093
+ case TD_STSTCS_DATABASE_LIST:
2094
+ return definedDatabases(nw->ptr(), nw->datalen);
2095
+ case TD_STSTCS_SYSTEM_VARIABLES:
2096
+ return systemVariables(nw->ptr(), nw->datalen);
2097
+ case TD_STSTCS_STATUS_VARIABLES:
2098
+ return statusVariables(nw->ptr(), nw->datalen);
2099
+ case TD_STSTCS_SCHEMA_TABLE_LIST:
2100
+ return schemaTables(nw->ptr(), nw->datalen);
2101
+ case TD_STSTCS_TABLE_LIST:
2102
+ return definedTables(nw->ptr(), nw->datalen);
2103
+ case TD_STSTCS_VIEW_LIST:
2104
+ return definedViews(nw->ptr(), nw->datalen);
2105
+ case TD_STSTCS_SLAVE_STATUS:
2106
+ return slaveStatus(nw);
2107
+ case TD_STSTCS_SLAVE_HOSTS:
2108
+ return slaveHosts(nw);
2109
+ case TD_STSTCS_SLAVE_CHANNELS:
2110
+ return channels(nw->ptr(), nw->datalen);
2111
+ case TD_STSTCS_SLAVE_CHANNELS_LOCK:
2112
+ {
2113
+ safeLockReadChannels readChannels(this);
2114
+ if (readChannels.lock())
2115
+ return readChannels.execute(nw->ptr(), nw->datalen);
2116
+ m_req.reset();
2117
+ m_req.result = STATUS_LOCK_ERROR;
2118
+ break;
2119
+ }
2120
+ case TD_STSTCS_EXTENDED_VARIABLES:
2121
+ return extendedVariables(nw);
2122
+ default:
2123
+ m_req.reset();
2124
+ m_req.result = STATUS_NOSUPPORT_OP;
2125
+ break;
2126
+ }
2127
+ }else
1937
2128
  {
1938
- case TD_STSTCS_READ:
1939
- return read(nw->ptr(), nw->datalen);
1940
- case TD_STSTCS_DATABASE_LIST:
1941
- return definedDatabases(nw->ptr(), nw->datalen);
1942
- case TD_STSTCS_SYSTEM_VARIABLES:
1943
- return systemVariables(nw->ptr(), nw->datalen);
1944
- case TD_STSTCS_STATUS_VARIABLES:
1945
- return statusVariables(nw->ptr(), nw->datalen);
1946
- case TD_STSTCS_SCHEMA_TABLE_LIST:
1947
- return schemaTables(nw->ptr(), nw->datalen);
1948
- case TD_STSTCS_TABLE_LIST:
1949
- return definedTables(nw->ptr(), nw->datalen);
1950
- case TD_STSTCS_VIEW_LIST:
1951
- return definedViews(nw->ptr(), nw->datalen);
1952
- case TD_STSTCS_SLAVE_STATUS:
1953
- return slaveStatus(nw);
1954
- default:
1955
2129
  m_req.reset();
1956
- m_req.result = STATUS_NOSUPPORT_OP;
1957
- break;
2130
+ m_req.result = SERVER_CLIENT_NOT_COMPATIBLE;
1958
2131
  }
1959
- }else
2132
+ nw->datalen = m_req.serialize(NULL, nw->ptr());
2133
+ }
2134
+ catch (bzs::rtl::exception& e)
1960
2135
  {
1961
- m_req.reset();
1962
- m_req.result = SERVER_CLIENT_NOT_COMPATIBLE;
2136
+ std::string s = *getMsg(e);
2137
+ const int* code = getCode(e);
2138
+ if (code)
2139
+ m_req.result = *code;
2140
+ else
2141
+ {
2142
+ m_req.result = 20000;
2143
+ s = boost::diagnostic_information(e);
2144
+ }
2145
+ char buf[256];
2146
+ sprintf_s(buf, 256, "Stastics operation %d : ", (int)op);
2147
+ s.insert(0, buf);
2148
+ printWarningMessage(code, &s);
2149
+ }
2150
+ catch (...)
2151
+ {
2152
+ try
2153
+ {
2154
+ DEBUG_ERROR_MEMDUMP(20001, "error", m_req.m_readBuffer,
2155
+ *((unsigned int*)m_req.m_readBuffer))
2156
+ m_req.reset();
2157
+ m_req.result = 20001;
2158
+ dumpStdErr(op, m_req, NULL);
2159
+ }
2160
+ catch(...){}
1963
2161
  }
1964
- nw->datalen = m_req.serialize(NULL, nw->ptr());
1965
2162
  return EXECUTE_RESULT_SUCCESS;
1966
2163
  }
1967
2164
 
@@ -1978,6 +2175,20 @@ commandExecuter::~commandExecuter()
1978
2175
  m_dbExec.reset();
1979
2176
  }
1980
2177
 
2178
+ int commandExecuter::execute(netsvc::server::netWriter* nw)
2179
+ {
2180
+ if (m_req.op == TD_STASTISTICS)
2181
+ return connMgrExecuter(m_req, (unsigned __int64)m_dbExec->mod(),
2182
+ m_dbExec->m_blobBuffer).commandExec(nw);
2183
+ int ret = m_dbExec->commandExec(m_req, nw);
2184
+
2185
+ // Start blocking mode need lock slave servers first.
2186
+ // therefore
2187
+ if (isTrxBlocking() && m_dbExec->trxProcessing() == 0)
2188
+ return EXECUTE_RESULT_SEND_QUIT;
2189
+ return ret;
2190
+ }
2191
+
1981
2192
  size_t commandExecuter::perseRequestEnd(const char* p, size_t transfered,
1982
2193
  bool& comp) const
1983
2194
  {