bool do_command(atrt_config& config){ #ifdef _WIN32 return true; #endif MYSQL* mysql= find_atrtdb_client(config); if (!mysql) return true; AtrtClient atrtdb(mysql); SqlResultSet command; if (!atrtdb.doQuery("SELECT * FROM command " \ "WHERE state = 'new' ORDER BY id LIMIT 1", command)){ g_logger.critical("query failed"); return false; } if (command.numRows() == 0) return true; uint id= command.columnAsInt("id"); uint cmd= command.columnAsInt("cmd"); g_logger.info("Got command, id: %d, cmd: %d", id, cmd); // command.print(); // Set state of command to running if (!ack_command(atrtdb, id, "running")) return false; switch (cmd){ case AtrtClient::ATCT_CHANGE_VERSION: if (!do_change_version(config, command, atrtdb)) return false; break; case AtrtClient::ATCT_RESET_PROC: if (!do_reset_proc(config, command, atrtdb)) return false; break; default: command.print(); g_logger.error("got unknown command: %d", cmd); return false; } // Set state of command to done if (!ack_command(atrtdb, id, "done")) return false; g_logger.info("done!"); return true; }
unsigned long long DbUtil::selectCountTable(const char * table) { BaseString query; SqlResultSet result; query.assfmt("select count(*) as count from %s", table); if (!doQuery(query, result)) { printError("select count(*) failed"); return -1; } return result.columnAsLong("count"); }
bool AtrtClient::doCommand(AtrtCommandType type, const Properties& args){ int running_timeout= 10; int total_timeout= 120; int commandId= writeCommand(type, args); if (commandId == -1){ g_err << "Failed to write command" << endl; return false; } while (true){ SqlResultSet result; if (!readCommand(commandId, result)) { result.print(); g_err << "Failed to read command "<< commandId << endl; return false; } // Get first row result.next(); // Check if command has completed BaseString state(result.column("state")); if (state == "done") { return true; } if (state == "new"){ if (!running_timeout--){ g_err << "Timeout while waiting for command " << commandId << " to start run" << endl; return false; } } else if (!total_timeout--){ g_err << "Timeout while waiting for result of command " << commandId << endl; return false; } NdbSleep_SecSleep(1); } return false; }
int verifySlave(BaseString& sqlStm, BaseString& db, BaseString& column) { SqlResultSet result; float masterSum; float slaveSum; //Create SQL Objects DbUtil master(db.c_str()); DbUtil slave(db.c_str(), ".1.slave"); if(!syncSlaveWithMaster()) { g_err << "Verify Slave -> Syncing with slave failed" << endl; return NDBT_FAILED; } //Login to Master if (!master.connect()) { g_err << "Verify Slave -> connect master failed" << endl; return NDBT_FAILED; } if(!master.doQuery(sqlStm.c_str(),result)) { return NDBT_FAILED; } masterSum = result.columnAsInt(column.c_str()); //Login to slave if (!slave.connect()) { return NDBT_FAILED; } if(!slave.doQuery(sqlStm.c_str(),result)) { return NDBT_FAILED; } slaveSum = result.columnAsInt(column.c_str()); if(masterSum != slaveSum) { g_err << "VerifySlave -> masterSum != slaveSum..." << endl; return NDBT_FAILED; } return NDBT_OK; }
RowsPtr EngineBase::select(const Expression &what, const Expression &from, const Expression &where, const Expression &group_by, const Expression &having, const Expression &order_by, int max_rows, bool for_update) { SqlResultSet rs = select_iter(SelectExpr(what).from_(from). where_(where).group_by_(group_by).having_(having). order_by_(order_by).for_update(for_update)); RowsPtr rows(new Rows); copy_no_more_than_n(rs.begin(), rs.end(), max_rows, back_inserter(*rows)); return rows; }
int runTestAtrtClient(NDBT_Context* ctx, NDBT_Step* step){ AtrtClient atrt; SqlResultSet clusters; if (!atrt.getClusters(clusters)) return NDBT_FAILED; int i= 0; while(clusters.next()) { ndbout << clusters.column("name") << endl; if (i++ == 1){ ndbout << "removing: " << clusters.column("name") << endl; clusters.remove(); } } clusters.reset(); while(clusters.next()) { ndbout << clusters.column("name") << endl; } return NDBT_OK; }
Strings OracleDialect::get_tables(SqlConnection &conn) { Strings table; auto_ptr<SqlCursor> cursor = conn.new_cursor(); String query = _T("SELECT table_name FROM all_tables where owner = (SELECT USER FROM DUAL)"); cursor->prepare(query); Values params; SqlResultSet rs = cursor->exec(params); for (SqlResultSet::iterator i = rs.begin(); i != rs.end(); ++i) { table.push_back((*i)[0].second.as_string()); } return table; }
SqlResultSet EngineBase::select_iter(const Expression &select_expr) { SqlGeneratorOptions options(NO_QUOTES, get_dialect()->has_for_update(), true, get_conn()->get_driver()->numbered_params(), (Yb::SqlPagerModel)get_dialect()->pager_model()); SqlGeneratorContext ctx; String sql = select_expr.generate_sql(options, &ctx); auto_ptr<SqlCursor> cursor = get_conn()->new_cursor(); cursor->prepare(sql); SqlResultSet rs = cursor->exec(ctx.params_); rs.own(cursor); return rs; }
bool DbUtil::doQuery(const char* query, const Properties& args, SqlResultSet& result){ if (!runQuery(query, args, result)) return false; result.get_row(0); // Load first row return true; }
static bool do_reset_proc(atrt_config& config, SqlResultSet& command, AtrtClient& atrtdb){ uint process_id= command.columnAsInt("process_id"); g_logger.info("Reset process: %d", process_id); // Get the process if (process_id > config.m_processes.size()){ g_logger.critical("Invalid process id %d", process_id); return false; } atrt_process& proc= *config.m_processes[process_id]; g_logger.info("stopping process..."); if (!stop_process(proc)) return false; if (proc.m_save.m_saved) { ndbout << "before: " << proc << endl; proc.m_proc= proc.m_save.m_proc; proc.m_save.m_saved= false; proc.m_proc.m_id= -1; ndbout << "after: " << proc << endl; } else { ndbout << "process has not changed" << endl; } g_logger.info("starting process..."); if (!start_process(proc)) return false; return true; }
bool DbUtil::runQuery(const char* sql, const Properties& args, SqlResultSet& rows){ clear_error(); rows.clear(); if (!isConnected()) return false; assert(m_mysql); g_debug << "runQuery: " << endl << " sql: '" << sql << "'" << endl; MYSQL_STMT *stmt= mysql_stmt_init(m_mysql); if (mysql_stmt_prepare(stmt, sql, (unsigned long)strlen(sql))) { report_error("Failed to prepare: ", m_mysql); return false; } uint params= mysql_stmt_param_count(stmt); MYSQL_BIND *bind_param = new MYSQL_BIND[params]; NdbAutoObjArrayPtr<MYSQL_BIND> _guard(bind_param); memset(bind_param, 0, params * sizeof(MYSQL_BIND)); for(uint i= 0; i < mysql_stmt_param_count(stmt); i++) { BaseString name; name.assfmt("%d", i); // Parameters are named 0, 1, 2... if (!args.contains(name.c_str())) { g_err << "param " << i << " missing" << endl; assert(false); } PropertiesType t; Uint32 val_i; const char* val_s; args.getTypeOf(name.c_str(), &t); switch(t) { case PropertiesType_Uint32: args.get(name.c_str(), &val_i); bind_param[i].buffer_type= MYSQL_TYPE_LONG; bind_param[i].buffer= (char*)&val_i; g_debug << " param" << name.c_str() << ": " << val_i << endl; break; case PropertiesType_char: args.get(name.c_str(), &val_s); bind_param[i].buffer_type= MYSQL_TYPE_STRING; bind_param[i].buffer= (char*)val_s; bind_param[i].buffer_length= (unsigned long)strlen(val_s); g_debug << " param" << name.c_str() << ": " << val_s << endl; break; default: assert(false); break; } } if (mysql_stmt_bind_param(stmt, bind_param)) { report_error("Failed to bind param: ", m_mysql); mysql_stmt_close(stmt); return false; } if (mysql_stmt_execute(stmt)) { report_error("Failed to execute: ", m_mysql); mysql_stmt_close(stmt); return false; } /* Update max_length, making it possible to know how big buffers to allocate */ my_bool one= 1; mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one); if (mysql_stmt_store_result(stmt)) { report_error("Failed to store result: ", m_mysql); mysql_stmt_close(stmt); return false; } uint row= 0; MYSQL_RES* res= mysql_stmt_result_metadata(stmt); if (res != NULL) { MYSQL_FIELD *fields= mysql_fetch_fields(res); uint num_fields= mysql_num_fields(res); MYSQL_BIND *bind_result = new MYSQL_BIND[num_fields]; NdbAutoObjArrayPtr<MYSQL_BIND> _guard1(bind_result); memset(bind_result, 0, num_fields * sizeof(MYSQL_BIND)); for (uint i= 0; i < num_fields; i++) { unsigned long buf_len= sizeof(int); switch(fields[i].type){ case MYSQL_TYPE_STRING: buf_len = fields[i].length + 1; break; case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VAR_STRING: buf_len= fields[i].max_length + 1; break; case MYSQL_TYPE_LONGLONG: buf_len= sizeof(long long); break; case MYSQL_TYPE_LONG: buf_len = sizeof(long); break; default: break; } bind_result[i].buffer_type= fields[i].type; bind_result[i].buffer= malloc(buf_len); bind_result[i].buffer_length= buf_len; bind_result[i].is_null = (my_bool*)malloc(sizeof(my_bool)); * bind_result[i].is_null = 0; } if (mysql_stmt_bind_result(stmt, bind_result)){ report_error("Failed to bind result: ", m_mysql); mysql_stmt_close(stmt); return false; } while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA) { Properties curr(true); for (uint i= 0; i < num_fields; i++){ if (* bind_result[i].is_null) continue; switch(fields[i].type){ case MYSQL_TYPE_STRING: ((char*)bind_result[i].buffer)[fields[i].max_length] = 0; case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VAR_STRING: curr.put(fields[i].name, (char*)bind_result[i].buffer); break; case MYSQL_TYPE_LONGLONG: curr.put64(fields[i].name, *(unsigned long long*)bind_result[i].buffer); break; default: curr.put(fields[i].name, *(int*)bind_result[i].buffer); break; } } rows.put("row", row++, &curr); } mysql_free_result(res); for (uint i= 0; i < num_fields; i++) { free(bind_result[i].buffer); free(bind_result[i].is_null); } } // Save stats in result set rows.put("rows", row); rows.put64("affected_rows", mysql_affected_rows(m_mysql)); rows.put("mysql_errno", mysql_errno(m_mysql)); rows.put("mysql_error", mysql_error(m_mysql)); rows.put("mysql_sqlstate", mysql_sqlstate(m_mysql)); rows.put64("insert_id", mysql_insert_id(m_mysql)); mysql_stmt_close(stmt); return true; }
bool syncSlaveWithMaster() { /* We need to look at the MAX epoch of the mysql.ndb_binlog_index table so we will know when the slave has caught up */ SqlResultSet result; unsigned long long masterEpoch = 0; unsigned long long slaveEpoch = 0; unsigned long long slaveEpochOld = 0; int maxLoops = 100; int loopCnt = 0; //Create a DbUtil object for the master DbUtil master("mysql"); //Login to Master if (!master.connect()) { g_err << "sync connect to master failed" << endl; return false; } //Get max epoch from master if(!master.doQuery("SELECT MAX(epoch) FROM mysql.ndb_binlog_index", result)) { g_err << "Select max(epoch) SQL failed" << endl; return false; } masterEpoch = result.columnAsLong("epoch"); /* Now we will pull current epoch from slave. If not the same as master, we will continue to retrieve the epoch and compare until it matches or we reach the max loops allowed. */ //Create a dbutil object for the slave DbUtil slave("mysql", ".1.slave"); //Login to slave if (!slave.connect()) { g_err << "sync connect to slave failed" << endl; return false; } while(slaveEpoch != masterEpoch && loopCnt < maxLoops) { if(!slave.doQuery("SELECT epoch FROM mysql.ndb_apply_status",result)) { g_err << "Select epoch SQL on slave failed" << endl; return false; } result.print(); if (result.numRows() > 0) slaveEpoch = result.columnAsLong("epoch"); if(slaveEpoch != slaveEpochOld) { slaveEpochOld = slaveEpoch; if(loopCnt > 0) loopCnt--; sleep(3); } else { sleep(1); loopCnt++; } } if(slaveEpoch != masterEpoch) { g_err << "Slave not in sync with master!" << endl; return false; } return true; }
static int runUpgrade_Half(NDBT_Context* ctx, NDBT_Step* step) { // Assuming 2 replicas AtrtClient atrt; const bool waitNode = ctx->getProperty("WaitNode", Uint32(0)) != 0; const bool event = ctx->getProperty("CreateDropEvent", Uint32(0)) != 0; const char * args = ""; if (ctx->getProperty("KeepFS", Uint32(0)) != 0) { args = "--initial=0"; } NodeSet mgmdNodeSet = (NodeSet) ctx->getProperty("MgmdNodeSet", Uint32(0)); NodeSet ndbdNodeSet = (NodeSet) ctx->getProperty("NdbdNodeSet", Uint32(0)); SqlResultSet clusters; if (!atrt.getClusters(clusters)) return NDBT_FAILED; while (clusters.next()) { uint clusterId= clusters.columnAsInt("id"); SqlResultSet tmp_result; if (!atrt.getConnectString(clusterId, tmp_result)) return NDBT_FAILED; NdbRestarter restarter(tmp_result.column("connectstring")); restarter.setReconnect(true); // Restarting mgmd g_err << "Cluster '" << clusters.column("name") << "@" << tmp_result.column("connectstring") << "'" << endl; if(restarter.waitClusterStarted()) return NDBT_FAILED; // Restart ndb_mgmd(s) SqlResultSet mgmds; if (!atrt.getMgmds(clusterId, mgmds)) return NDBT_FAILED; uint mgmdCount = mgmds.numRows(); uint restartCount = getNodeCount(mgmdNodeSet, mgmdCount); ndbout << "Restarting " << restartCount << " of " << mgmdCount << " mgmds" << endl; while (mgmds.next() && restartCount --) { ndbout << "Restart mgmd" << mgmds.columnAsInt("node_id") << endl; if (!atrt.changeVersion(mgmds.columnAsInt("id"), "")) return NDBT_FAILED; if(restarter.waitConnected()) return NDBT_FAILED; } NdbSleep_SecSleep(5); // TODO, handle arbitration // Restart one ndbd in each node group SqlResultSet ndbds; if (!atrt.getNdbds(clusterId, ndbds)) return NDBT_FAILED; Vector<NodeInfo> nodes; while (ndbds.next()) { struct NodeInfo n; n.nodeId = ndbds.columnAsInt("node_id"); n.processId = ndbds.columnAsInt("id"); n.nodeGroup = restarter.getNodeGroup(n.nodeId); nodes.push_back(n); } uint ndbdCount = ndbds.numRows(); restartCount = getNodeCount(ndbdNodeSet, ndbdCount); ndbout << "Restarting " << restartCount << " of " << ndbdCount << " ndbds" << endl; int nodesarray[256]; int cnt= 0; Bitmask<4> seen_groups; Bitmask<4> restarted_nodes; for (Uint32 i = 0; (i<nodes.size() && restartCount); i++) { int nodeId = nodes[i].nodeId; int processId = nodes[i].processId; int nodeGroup= nodes[i].nodeGroup; if (seen_groups.get(nodeGroup)) { // One node in this node group already down continue; } seen_groups.set(nodeGroup); restarted_nodes.set(nodeId); ndbout << "Restart node " << nodeId << endl; if (!atrt.changeVersion(processId, args)) return NDBT_FAILED; if (waitNode) { restarter.waitNodesNoStart(&nodeId, 1); } nodesarray[cnt++]= nodeId; restartCount--; } if (!waitNode) { if (restarter.waitNodesNoStart(nodesarray, cnt)) return NDBT_FAILED; } ndbout << "Starting and wait for started..." << endl; if (restarter.startAll()) return NDBT_FAILED; if (restarter.waitClusterStarted()) return NDBT_FAILED; if (event && createDropEvent(ctx, step)) { return NDBT_FAILED; } ndbout << "Half started" << endl; if (ctx->getProperty("HalfStartedHold", (Uint32)0) != 0) { while (ctx->getProperty("HalfStartedHold", (Uint32)0) != 0) { ndbout << "Half started holding..." << endl; ctx->setProperty("HalfStartedDone", (Uint32)1); NdbSleep_SecSleep(30); } ndbout << "Got half started continue..." << endl; } // Restart the remaining nodes cnt= 0; for (Uint32 i = 0; (i<nodes.size() && restartCount); i++) { int nodeId = nodes[i].nodeId; int processId = nodes[i].processId; if (restarted_nodes.get(nodeId)) continue; ndbout << "Restart node " << nodeId << endl; if (!atrt.changeVersion(processId, args)) return NDBT_FAILED; if (waitNode) { restarter.waitNodesNoStart(&nodeId, 1); } nodesarray[cnt++]= nodeId; restartCount --; } if (!waitNode) { if (restarter.waitNodesNoStart(nodesarray, cnt)) return NDBT_FAILED; } ndbout << "Starting and wait for started..." << endl; if (restarter.startAll()) return NDBT_FAILED; if (restarter.waitClusterStarted()) return NDBT_FAILED; if (event && createDropEvent(ctx, step)) { return NDBT_FAILED; } } return NDBT_OK; }
ColumnsInfo OracleDialect::get_columns(SqlConnection &conn, const String &table) { ColumnsInfo ci; auto_ptr<SqlCursor> cursor = conn.new_cursor(); String query = _T("SELECT col.column_name, col.data_type, col.data_length, col.nullable, col.data_default FROM ALL_TAB_COLUMNS col WHERE col.TABLE_NAME = '") +table + _T("' AND col.OWNER = (SELECT USER FROM DUAL)"); cursor->prepare(query); Values params; SqlResultSet rs = cursor->exec(params); for (SqlResultSet::iterator i = rs.begin(); i != rs.end(); ++i) { ColumnInfo x; for (Row::const_iterator j = i->begin(); j != i->end(); ++j) { if (_T("COLUMN_NAME") == j->first) { x.name = str_to_upper(j->second.as_string()); } else if (_T("DATA_TYPE") == j->first) { x.type = str_to_upper(j->second.as_string()); if (_T("VARCHAR2") == x.type) { ++j; if (_T("DATA_LENGTH") == j->first) { x.size = j->second.as_integer(); } } } else if (_T("NULLABLE") == j->first) { x.notnull = _T("N") == j->second.as_string(); } else if (_T("DATA_DEFAULT") == j->first) { if (!j->second.is_null()) x.default_value = j->second.as_string(); } } ci.push_back(x); } String querypk = _T("SELECT cols.position FROM all_constraints cons, all_cons_columns cols WHERE cols.table_name = '") +table+ _T("' AND cons.constraint_type = 'P' AND cons.constraint_name = cols.constraint_name AND cons.owner = cols.owner"); cursor->prepare(querypk); Values paramspk; SqlResultSet rspk = cursor->exec(paramspk); for (SqlResultSet::iterator i = rspk.begin(); i != rspk.end(); ++i) { Row::const_iterator j = i->begin(); if (j != i-> end()) { ci[j->second.as_integer() - 1].pk = true; } } String q2 =_T("SELECT substr(c_src.COLUMN_NAME, 1, 20) as SRC_COLUMN, c_dest.TABLE_NAME as DEST_TABLE, substr(c_dest.COLUMN_NAME, 1, 20) as DEST_COLUMN FROM ALL_CONSTRAINTS c_list, ALL_CONS_COLUMNS c_src, ALL_CONS_COLUMNS c_dest WHERE c_list.CONSTRAINT_NAME = c_src.CONSTRAINT_NAME AND c_list.R_CONSTRAINT_NAME = c_dest.CONSTRAINT_NAME AND c_list.CONSTRAINT_TYPE = 'R' AND c_src.TABLE_NAME = '") + table + _T("'"); cursor->prepare(q2); Values params2; SqlResultSet rs2 = cursor->exec(params2); for (SqlResultSet::iterator i = rs2.begin(); i != rs2.end(); ++i) { String fk_column, fk_table, fk_table_key; for (Row::const_iterator j = i->begin(); j != i->end(); ++j) { if (_T("DEST_TABLE") == j->first) { if (!j->second.is_null()) { fk_table = j->second.as_string(); } } else if (_T("DEST_COLUMN") == j->first) { if (!j->second.is_null()) { fk_table_key = j->second.as_string(); } } else if (_T("SRC_COLUMN") == j->first) { if (!j->second.is_null()) { fk_column = j->second.as_string(); } } } for (ColumnsInfo::iterator k = ci.begin(); k != ci.end(); ++k) { if (k->name == fk_column) { k->fk_table = fk_table; k->fk_table_key = fk_table_key; break; } } } return ci; }
int runUpgrade_NR1(NDBT_Context* ctx, NDBT_Step* step) { AtrtClient atrt; NodeSet mgmdNodeSet = (NodeSet) ctx->getProperty("MgmdNodeSet", Uint32(0)); NodeSet ndbdNodeSet = (NodeSet) ctx->getProperty("NdbdNodeSet", Uint32(0)); SqlResultSet clusters; if (!atrt.getClusters(clusters)) return NDBT_FAILED; while (clusters.next()) { uint clusterId= clusters.columnAsInt("id"); SqlResultSet tmp_result; if (!atrt.getConnectString(clusterId, tmp_result)) return NDBT_FAILED; NdbRestarter restarter(tmp_result.column("connectstring")); restarter.setReconnect(true); // Restarting mgmd g_err << "Cluster '" << clusters.column("name") << "@" << tmp_result.column("connectstring") << "'" << endl; if (restarter.waitClusterStarted()) return NDBT_FAILED; // Restart ndb_mgmd(s) SqlResultSet mgmds; if (!atrt.getMgmds(clusterId, mgmds)) return NDBT_FAILED; uint mgmdCount = mgmds.numRows(); uint restartCount = getNodeCount(mgmdNodeSet, mgmdCount); ndbout << "Restarting " << restartCount << " of " << mgmdCount << " mgmds" << endl; while (mgmds.next() && restartCount --) { ndbout << "Restart mgmd " << mgmds.columnAsInt("node_id") << endl; if (!atrt.changeVersion(mgmds.columnAsInt("id"), "")) return NDBT_FAILED; if (restarter.waitConnected()) return NDBT_FAILED; ndbout << "Connected to mgmd"<< endl; } ndbout << "Waiting for started"<< endl; if (restarter.waitClusterStarted()) return NDBT_FAILED; ndbout << "Started"<< endl; // Restart ndbd(s) SqlResultSet ndbds; if (!atrt.getNdbds(clusterId, ndbds)) return NDBT_FAILED; uint ndbdCount = ndbds.numRows(); restartCount = getNodeCount(ndbdNodeSet, ndbdCount); ndbout << "Restarting " << restartCount << " of " << ndbdCount << " ndbds" << endl; while(ndbds.next() && restartCount --) { int nodeId = ndbds.columnAsInt("node_id"); int processId = ndbds.columnAsInt("id"); ndbout << "Restart node " << nodeId << endl; if (!atrt.changeVersion(processId, "")) return NDBT_FAILED; if (restarter.waitNodesNoStart(&nodeId, 1)) return NDBT_FAILED; if (restarter.startNodes(&nodeId, 1)) return NDBT_FAILED; if (restarter.waitNodesStarted(&nodeId, 1)) return NDBT_FAILED; if (createDropEvent(ctx, step)) return NDBT_FAILED; } } ctx->stopTest(); return NDBT_OK; }
bool DbUtil::runQuery(const char* sql, const Properties& args, SqlResultSet& rows){ rows.clear(); if (!isConnected()) return false; g_debug << "runQuery: " << endl << " sql: '" << sql << "'" << endl; MYSQL_STMT *stmt= mysql_stmt_init(m_mysql); if (mysql_stmt_prepare(stmt, sql, strlen(sql))) { g_err << "Failed to prepare: " << mysql_error(m_mysql) << endl; return false; } uint params= mysql_stmt_param_count(stmt); MYSQL_BIND bind_param[params]; bzero(bind_param, sizeof(bind_param)); for(uint i= 0; i < mysql_stmt_param_count(stmt); i++) { BaseString name; name.assfmt("%d", i); // Parameters are named 0, 1, 2... if (!args.contains(name.c_str())) { g_err << "param " << i << " missing" << endl; assert(false); } PropertiesType t; Uint32 val_i; const char* val_s; args.getTypeOf(name.c_str(), &t); switch(t) { case PropertiesType_Uint32: args.get(name.c_str(), &val_i); bind_param[i].buffer_type= MYSQL_TYPE_LONG; bind_param[i].buffer= (char*)&val_i; g_debug << " param" << name.c_str() << ": " << val_i << endl; break; case PropertiesType_char: args.get(name.c_str(), &val_s); bind_param[i].buffer_type= MYSQL_TYPE_STRING; bind_param[i].buffer= (char*)val_s; bind_param[i].buffer_length= strlen(val_s); g_debug << " param" << name.c_str() << ": " << val_s << endl; break; default: assert(false); break; } } if (mysql_stmt_bind_param(stmt, bind_param)) { g_err << "Failed to bind param: " << mysql_error(m_mysql) << endl; mysql_stmt_close(stmt); return false; } if (mysql_stmt_execute(stmt)) { g_err << "Failed to execute: " << mysql_error(m_mysql) << endl; mysql_stmt_close(stmt); return false; } /* Update max_length, making it possible to know how big buffers to allocate */ my_bool one= 1; mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one); if (mysql_stmt_store_result(stmt)) { g_err << "Failed to store result: " << mysql_error(m_mysql) << endl; mysql_stmt_close(stmt); return false; } uint row= 0; MYSQL_RES* res= mysql_stmt_result_metadata(stmt); if (res != NULL) { MYSQL_FIELD *fields= mysql_fetch_fields(res); uint num_fields= mysql_num_fields(res); MYSQL_BIND bind_result[num_fields]; bzero(bind_result, sizeof(bind_result)); for (uint i= 0; i < num_fields; i++) { if (is_int_type(fields[i].type)){ bind_result[i].buffer_type= MYSQL_TYPE_LONG; bind_result[i].buffer= malloc(sizeof(int)); } else { uint max_length= fields[i].max_length + 1; bind_result[i].buffer_type= MYSQL_TYPE_STRING; bind_result[i].buffer= malloc(max_length); bind_result[i].buffer_length= max_length; } } if (mysql_stmt_bind_result(stmt, bind_result)){ g_err << "Failed to bind result: " << mysql_error(m_mysql) << endl; mysql_stmt_close(stmt); return false; } while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA) { Properties curr(true); for (uint i= 0; i < num_fields; i++){ if (is_int_type(fields[i].type)) curr.put(fields[i].name, *(int*)bind_result[i].buffer); else curr.put(fields[i].name, (char*)bind_result[i].buffer); } rows.put("row", row++, &curr); } mysql_free_result(res); for (uint i= 0; i < num_fields; i++) free(bind_result[i].buffer); } // Save stats in result set rows.put("rows", row); rows.put("affected_rows", mysql_affected_rows(m_mysql)); rows.put("mysql_errno", mysql_errno(m_mysql)); rows.put("mysql_error", mysql_error(m_mysql)); rows.put("mysql_sqlstate", mysql_sqlstate(m_mysql)); rows.put("insert_id", mysql_insert_id(m_mysql)); mysql_stmt_close(stmt); return true; }
static bool do_change_version(atrt_config& config, SqlResultSet& command, AtrtClient& atrtdb){ /** * TODO make option to restart "not" initial */ uint process_id= command.columnAsInt("process_id"); const char* process_args= command.column("process_args"); g_logger.info("Change version for process: %d, args: %s", process_id, process_args); // Get the process if (process_id > config.m_processes.size()){ g_logger.critical("Invalid process id %d", process_id); return false; } atrt_process& proc= *config.m_processes[process_id]; const char* new_prefix= g_prefix1 ? g_prefix1 : g_prefix; const char* old_prefix= g_prefix; const char *start= strstr(proc.m_proc.m_path.c_str(), old_prefix); if (!start){ /* Process path does not contain old prefix. * Perhaps it contains the new prefix - e.g. is already * upgraded? */ if (strstr(proc.m_proc.m_path.c_str(), new_prefix)) { /* Process is already upgraded, *assume* that this * is ok * Alternatives could be - error, or downgrade. */ g_logger.info("Process already upgraded"); return true; } g_logger.critical("Could not find '%s' in '%s'", old_prefix, proc.m_proc.m_path.c_str()); return false; } // Save current proc state if (proc.m_save.m_saved == false) { proc.m_save.m_proc= proc.m_proc; proc.m_save.m_saved= true; } g_logger.info("stopping process..."); if (!stop_process(proc)) return false; BaseString newEnv = set_env_var(proc.m_proc.m_env, BaseString("MYSQL_BASE_DIR"), BaseString(new_prefix)); proc.m_proc.m_env.assign(newEnv); ssize_t pos = proc.m_proc.m_path.lastIndexOf('/') + 1; BaseString exename(proc.m_proc.m_path.substr(pos)); char * exe = find_bin_path(new_prefix, exename.c_str()); proc.m_proc.m_path = exe; if (exe) { free(exe); } if (process_args && strlen(process_args)) { /* Beware too long args */ proc.m_proc.m_args.append(" "); proc.m_proc.m_args.append(process_args); } { /** * In 5.5...binaries aren't compiled with rpath * So we need an explicit LD_LIBRARY_PATH * So when upgrading..we need to change LD_LIBRARY_PATH * So I hate 5.5... */ #if defined(__MACH__) ssize_t p0 = proc.m_proc.m_env.indexOf(" DYLD_LIBRARY_PATH="); #else ssize_t p0 = proc.m_proc.m_env.indexOf(" LD_LIBRARY_PATH="); #endif ssize_t p1 = proc.m_proc.m_env.indexOf(' ', p0 + 1); BaseString part0 = proc.m_proc.m_env.substr(0, p0); BaseString part1 = proc.m_proc.m_env.substr(p1); proc.m_proc.m_env.assfmt("%s%s", part0.c_str(), part1.c_str()); BaseString lib(g_libmysqlclient_so_path); ssize_t pos = lib.lastIndexOf('/') + 1; BaseString libname(lib.substr(pos)); char * exe = find_bin_path(new_prefix, libname.c_str()); char * dir = dirname(exe); #if defined(__MACH__) proc.m_proc.m_env.appfmt(" DYLD_LIBRARY_PATH=%s", dir); #else proc.m_proc.m_env.appfmt(" LD_LIBRARY_PATH=%s", dir); #endif free(exe); free(dir); } ndbout << proc << endl; g_logger.info("starting process..."); if (!start_process(proc)) return false; return true; }
static bool do_change_version(atrt_config& config, SqlResultSet& command, AtrtClient& atrtdb){ /** * TODO make option to restart "not" initial */ uint process_id= command.columnAsInt("process_id"); const char* process_args= command.column("process_args"); g_logger.info("Change version for process: %d, args: %s", process_id, process_args); // Get the process if (process_id > config.m_processes.size()){ g_logger.critical("Invalid process id %d", process_id); return false; } atrt_process& proc= *config.m_processes[process_id]; const char* new_prefix= g_prefix1 ? g_prefix1 : g_prefix; const char* old_prefix= g_prefix; const char *start= strstr(proc.m_proc.m_path.c_str(), old_prefix); if (!start){ /* Process path does not contain old prefix. * Perhaps it contains the new prefix - e.g. is already * upgraded? */ if (strstr(proc.m_proc.m_path.c_str(), new_prefix)) { /* Process is already upgraded, *assume* that this * is ok * Alternatives could be - error, or downgrade. */ g_logger.info("Process already upgraded"); return true; } g_logger.critical("Could not find '%s' in '%s'", old_prefix, proc.m_proc.m_path.c_str()); return false; } // Save current proc state if (proc.m_save.m_saved == false) { proc.m_save.m_proc= proc.m_proc; proc.m_save.m_saved= true; } g_logger.info("stopping process..."); if (!stop_process(proc)) return false; BaseString newEnv = set_env_var(proc.m_proc.m_env, BaseString("MYSQL_BASE_DIR"), BaseString(new_prefix)); proc.m_proc.m_env.assign(newEnv); BaseString suffix(proc.m_proc.m_path.substr(strlen(old_prefix))); proc.m_proc.m_path.assign(new_prefix).append(suffix); if (process_args && strlen(process_args)) { /* Beware too long args */ proc.m_proc.m_args.append(" "); proc.m_proc.m_args.append(process_args); } ndbout << proc << endl; g_logger.info("starting process..."); if (!start_process(proc)) return false; return true; }
int runTestDbUtil(NDBT_Context* ctx, NDBT_Step* step){ DbUtil sql; { // Select all rows from mysql.user SqlResultSet result; if (!sql.doQuery("SELECT * FROM mysql.user", result)) return NDBT_FAILED; // result.print(); while(result.next()) { ndbout << result.column("host") << ", " << result.column("uSer") << ", " << result.columnAsInt("max_updates") << ", " << endl; } result.reset(); while(result.next()) { ndbout << result.column("host") << endl; } } { // No column name, query should fail Properties args; SqlResultSet result; if (sql.doQuery("SELECT * FROM mysql.user WHERE name=?", args, result)) return NDBT_FAILED; result.print(); } { // Select nonexisiting rows from mysql.user Properties args; SqlResultSet result; args.put("0", "no_such_host"); if (!sql.doQuery("SELECT * FROM mysql.user WHERE host=?", args, result)) return NDBT_FAILED; ndbout << "no rows" << endl; result.print(); // Change args to an find one row args.clear(); args.put("0", "localhost"); if (!sql.doQuery("SELECT host, user FROM mysql.user WHERE host=?", args, result)) return NDBT_FAILED; result.print(); } { if (!sql.doQuery("CREATE TABLE sql_client_test (a int, b varchar(255))")) return NDBT_FAILED; if (!sql.doQuery("INSERT INTO sql_client_test VALUES(1, 'hello'), (2, 'bye')")) return NDBT_FAILED; // Select all rows from sql_client_test SqlResultSet result; if (!sql.doQuery("SELECT * FROM sql_client_test", result)) return NDBT_FAILED; // result.print(); while(result.next()) { } // Select second row from sql_client_test Properties args; args.put("0", 2); if (!sql.doQuery("SELECT * FROM sql_client_test WHERE a=?", args,result)) return NDBT_FAILED; result.print(); result.reset(); while(result.next()) { ndbout << "a: " << result.columnAsInt("a") << endl; ndbout << "b: " << result.column("b") << endl; if (result.columnAsInt("a") != 2){ ndbout << "hepp1" << endl; return NDBT_FAILED; } if (strcmp(result.column("b"), "bye")){ ndbout << "hepp2" << endl; return NDBT_FAILED; } } if (sql.selectCountTable("sql_client_test") != 2) { ndbout << "Got wrong count" << endl; return NDBT_FAILED; } if (!sql.doQuery("DROP TABLE sql_client_test")) return NDBT_FAILED; } return NDBT_OK; }
static int runUpgrade_SR(NDBT_Context* ctx, NDBT_Step* step) { /* System restart upgrade. * Stop all data nodes * Change versions * Restart em together. */ AtrtClient atrt; NodeSet mgmdNodeSet = All; const char * args = ""; bool skipMgmds = (ctx->getProperty("SkipMgmds", Uint32(0)) != 0); SqlResultSet clusters; if (!atrt.getClusters(clusters)) return NDBT_FAILED; while (clusters.next()) { uint clusterId= clusters.columnAsInt("id"); SqlResultSet tmp_result; if (!atrt.getConnectString(clusterId, tmp_result)) return NDBT_FAILED; NdbRestarter restarter(tmp_result.column("connectstring")); restarter.setReconnect(true); // Restarting mgmd g_err << "Cluster '" << clusters.column("name") << "@" << tmp_result.column("connectstring") << "'" << endl; if(restarter.waitClusterStarted()) return NDBT_FAILED; /* Now restart to nostart state, prior to SR */ g_err << "Restarting all data nodes-nostart" << endl; if (restarter.restartAll2(NdbRestarter::NRRF_NOSTART) != 0) { g_err << "Failed to restart all" << endl; return NDBT_FAILED; } ndbout << "Waiting for no-start state" << endl; if (restarter.waitClusterNoStart() != 0) { g_err << "Failed waiting for NoStart state" << endl; return NDBT_FAILED; } // Restart ndb_mgmd(s) SqlResultSet mgmds; if (!atrt.getMgmds(clusterId, mgmds)) return NDBT_FAILED; uint mgmdCount = mgmds.numRows(); uint restartCount = getNodeCount(mgmdNodeSet, mgmdCount); if (!skipMgmds) { ndbout << "Restarting " << restartCount << " of " << mgmdCount << " mgmds" << endl; while (mgmds.next() && restartCount --) { ndbout << "Restart mgmd" << mgmds.columnAsInt("node_id") << endl; if (!atrt.changeVersion(mgmds.columnAsInt("id"), "")) return NDBT_FAILED; if(restarter.waitConnected()) return NDBT_FAILED; } NdbSleep_SecSleep(5); // TODO, handle arbitration } else { ndbout << "Skipping MGMD upgrade" << endl; } // Restart all ndbds SqlResultSet ndbds; if (!atrt.getNdbds(clusterId, ndbds)) return NDBT_FAILED; uint ndbdCount = ndbds.numRows(); restartCount = ndbdCount; ndbout << "Upgrading " << restartCount << " of " << ndbdCount << " ndbds" << endl; while (ndbds.next()) { uint nodeId = ndbds.columnAsInt("node_id"); uint processId = ndbds.columnAsInt("id"); ndbout << "Upgrading node " << nodeId << endl; if (!atrt.changeVersion(processId, args)) return NDBT_FAILED; } ndbout << "Waiting for no-start state" << endl; if (restarter.waitClusterNoStart() != 0) { g_err << "Failed waiting for NoStart state" << endl; return NDBT_FAILED; } ndbout << "Starting cluster (SR)" << endl; if (restarter.restartAll2(0) != 0) { g_err << "Error restarting all nodes" << endl; return NDBT_FAILED; } ndbout << "Waiting for cluster to start" << endl; if (restarter.waitClusterStarted() != 0) { g_err << "Failed waiting for Cluster start" << endl; return NDBT_FAILED; } ndbout << "Cluster started." << endl; } return NDBT_OK; }