diff --git a/checkin_notes b/checkin_notes index 2d3ff40a38..a38c05776b 100755 --- a/checkin_notes +++ b/checkin_notes @@ -15483,11 +15483,6 @@ Rom July 19 2004 Karl 2004-07-21 - fix bug in "couldn't find app" messages - - sched/ - message_handler.C - validator.C - - allow '.msi' as extension for installation package tools/ @@ -15502,3 +15497,42 @@ Karl 2004-07-21 old_news.php project.sample/ project_news.inc + + sched/ + message_handler.C + validator.C + +David 21 July 2004 + - Database optimization in the transitioner: + add several results in a single SQL insert statement + (using values (...),(...),(...)) + instead of separate inserts. + This is enabled by a BATCH_INSERT compile flag in transitioner.C + - Add a USE_TRANSACTIONS flag to transitioner. + Leave it off for now. + - For some reason we weren't processing the UPLOAD_URL symbol + in result templates. + Restore this, using the info in the config file. + - transitioner: if anything fails (result creation, WU update), quit. + - result.random must be initialize by caller on insert + (not too relevant since we don't use it anymore) + - start/commit_transaction are now members of DB_CONN + rather than DB_BASE_SPECIAL + - scheduler: in scan_work_array, do all "cheap" checks + (i.e. those that don't require DB access) + before releasing the semaphore. + Thus if all the results are infeasible, + we'll acquire/release the semaphore once, not 100 times. + - re-enable team name search + + db/ + boinc_db.C,h + db_base.C,h + html/user/ + team.php + team_lookup.php + sched/ + sched_send.C + transitioner.C + tools/ + backend_lib.C,h diff --git a/db/boinc_db.C b/db/boinc_db.C index 836a32e1c5..36718625da 100644 --- a/db/boinc_db.C +++ b/db/boinc_db.C @@ -492,6 +492,34 @@ void DB_RESULT::db_print(char* buf){ UNESCAPE(stderr_out); } +void DB_RESULT::db_print_values(char* buf){ + ESCAPE(xml_doc_out); + ESCAPE(stderr_out); + sprintf( + buf, + "(0, %d, %d, " + "%d, %d, %d, " + "%d, %d, " + "%d, %d, %d, " + "'%s', %.15e, " + "'%s', '%s', '%s', " + "%d, %d, %d, " + "%.15e, %.15e, %f, %d, " + "%d, %d, %d, %d)", + create_time, workunitid, + server_state, outcome, client_state, + hostid, userid, + report_deadline, sent_time, received_time, + name, cpu_time, + xml_doc_in, xml_doc_out, stderr_out, + batch, file_delete_state, validate_state, + claimed_credit, granted_credit, opaque, random, + app_version_num, appid, exit_status, teamid + ); + UNESCAPE(xml_doc_out); + UNESCAPE(stderr_out); +} + void DB_RESULT::db_parse(MYSQL_ROW &r) { int i=0; clear(); @@ -524,11 +552,6 @@ void DB_RESULT::db_parse(MYSQL_ROW &r) { teamid = atoi(r[i++]); } -int DB_RESULT::insert() { - random = lrand48(); - return DB_BASE::insert(); -} - void DB_MSG_FROM_HOST::db_print(char* buf) { ESCAPE(xml); sprintf(buf, diff --git a/db/boinc_db.h b/db/boinc_db.h index 48dfcea4c2..c654c5d0ce 100755 --- a/db/boinc_db.h +++ b/db/boinc_db.h @@ -533,9 +533,9 @@ public: class DB_RESULT : public DB_BASE, public RESULT { public: DB_RESULT(); - int insert(); int get_id(); void db_print(char*); + void db_print_values(char*); void db_parse(MYSQL_ROW &row); void operator=(RESULT& r) {RESULT::operator=(r);} }; diff --git a/db/db_base.C b/db/db_base.C index b138f72fcb..c0162b3035 100644 --- a/db/db_base.C +++ b/db/db_base.C @@ -60,6 +60,14 @@ const char* DB_CONN::error_string() { return mysql?mysql_error(mysql):"Not connected"; } +int DB_CONN::start_transaction() { + return do_query("START TRANSACTION"); +} + +int DB_CONN::commit_transaction() { + return do_query("COMMIT"); +} + DB_BASE::DB_BASE(DB_CONN& p, char *tn) : db(&p), table_name(tn) { is_high_priority = false; } @@ -76,6 +84,12 @@ int DB_BASE::insert() { return db->do_query(query); } +int DB_BASE::insert_batch(const char* values) { + char query[MAX_QUERY_LEN]; + sprintf(query, "insert into %s values %s", table_name, values); + return db->do_query(query); +} + // update an entire record // int DB_BASE::update() { @@ -253,17 +267,9 @@ int DB_BASE::sum(double& x, char* field, char* clause) { DB_BASE_SPECIAL::DB_BASE_SPECIAL(DB_CONN& p) : db(&p) { } -int DB_BASE_SPECIAL::start_transaction() { - return db->do_query("START TRANSACTION"); -} - -int DB_BASE_SPECIAL::commit_transaction() { - return db->do_query("COMMIT"); -} - // convert a string into a form that allows it to be used // in SQL queries delimited by single quotes: -// replace ' with \', \ with \\ +// replace ' with \', '\' with '\\' // void escape_string(char* field, int len) { char buf[MAX_QUERY_LEN]; diff --git a/db/db_base.h b/db/db_base.h index 1066cae6c7..5a0d2dc9b8 100644 --- a/db/db_base.h +++ b/db/db_base.h @@ -68,6 +68,8 @@ public: const char* error_string(); MYSQL* mysql; + int start_transaction(); + int commit_transaction(); }; // Base for derived classes that can access the DB @@ -77,6 +79,7 @@ class DB_BASE { public: DB_BASE(DB_CONN&, char *table_name); int insert(); + int insert_batch(const char*); int update(); int update_field(char*); int lookup_id(int id); @@ -106,9 +109,6 @@ public: DB_CONN* db; CURSOR cursor; - - int start_transaction(); - int commit_transaction(); }; void escape_string(char* field, int len); diff --git a/html/user/team.php b/html/user/team.php index 719fb4ec34..59584ede42 100644 --- a/html/user/team.php +++ b/html/user/team.php @@ -23,7 +23,7 @@ echo "
".PROJECT." participants may form teams.
diff --git a/html/user/team_lookup.php b/html/user/team_lookup.php index 30da1398dc..2977b18cee 100644 --- a/html/user/team_lookup.php +++ b/html/user/team_lookup.php @@ -12,14 +12,7 @@ $length = count($words); $name_lc = strtolower($team_name); - echo "Team lookup disabled"; - page_tail(); - exit(); - - $query = sprintf( - "select * from team where name_lc like '%s'", - "%$name_lc%" - ); + $query = "select * from team where name like '$name_lc%'"; $result_list = mysql_query($query); page_head("Search Results"); if ($result_list) { diff --git a/sched/sched_send.C b/sched/sched_send.C index de08a27785..98c743325d 100644 --- a/sched/sched_send.C +++ b/sched/sched_send.C @@ -490,47 +490,44 @@ static void scan_work_array( WU_RESULT& wu_result = ss.wu_results[i]; - // the following should be a critical section - // + // do fast checks on this wu_result; + // i.e. ones that don't require DB access + // if any check fails, continue + switch (wu_result.state) { case WR_STATE_EMPTY: case WR_STATE_CHECKED_OUT: continue; } - wu_result.state = WR_STATE_CHECKED_OUT; - unlock_sema(); - // from here on in this loop, don't continue; - // you can only goto dont_send (so that we reacquire semaphore) + if (wreq.infeasible_only && (wu_result.infeasible_count==0)) { + continue; + } if (wu_result.workunit.rsc_disk_bound > wreq.disk_available) { wreq.insufficient_disk = true; wu_result.infeasible_count++; - goto dont_send; - } - - if (wreq.infeasible_only && (wu_result.infeasible_count==0)) { - goto dont_send; + continue; } // don't send if we're already sending a result for same WU // if (already_in_reply(wu_result, reply)) { - goto dont_send; + continue; } // don't send if host can't handle it // wu = wu_result.workunit; - if (!wu_is_feasible(wu, reply.host, wreq, - sreq.resource_share_fraction) - ) { + if (!wu_is_feasible( + wu, reply.host, wreq, sreq.resource_share_fraction + )) { log_messages.printf( SCHED_MSG_LOG::DEBUG, "[HOST#%d] [WU#%d %s] WU is infeasible\n", reply.host.id, wu.id, wu.name ); wu_result.infeasible_count++; - goto dont_send; + continue; } // Find the app and app_version for the client's platform. @@ -540,14 +537,14 @@ static void scan_work_array( app = ss.lookup_app(wu.appid); found = sreq.has_version(*app); if (!found) { - goto dont_send; + continue; } avp = NULL; } else { found = find_app_version(wreq, wu, platform, ss, app, avp); if (!found) { wu_result.infeasible_count++; - goto dont_send; + continue; } // see if the core client is too old. @@ -555,12 +552,18 @@ static void scan_work_array( // isn't the result's fault // if (!app_core_compatible(wreq, *avp)) { - goto dont_send; + continue; } } + // end of fast checks - mark wu_result as checked out and release sema. + // from here on in this loop, don't continue on failure; + // instead, goto dont_send (so that we reacquire semaphore) + + wu_result.state = WR_STATE_CHECKED_OUT; + unlock_sema(); + // Don't send if we've already sent a result of this WU to this user. - // NOTE: do this check last since it involves a DB access // if (config.one_result_per_user_per_wu) { sprintf(buf, diff --git a/sched/transitioner.C b/sched/transitioner.C index ad0a421e30..a8d87c2dd4 100644 --- a/sched/transitioner.C +++ b/sched/transitioner.C @@ -47,6 +47,9 @@ using namespace std; #define SELECT_LIMIT 100 +#define BATCH_INSERT 1 +//#define USE_TRANSACTIONS 1 + int startup_time; SCHED_CONFIG config; R_RSA_PRIVATE_KEY key; @@ -59,7 +62,7 @@ int result_suffix(char* name) { return 0; } -void handle_wu( +int handle_wu( DB_TRANSITIONER_ITEM_SET& transitioner, std::vector