From e0189e8c21378434efb20d80fb8a3f7d576dfe08 Mon Sep 17 00:00:00 2001 From: Danny Auble <da@llnl.gov> Date: Tue, 27 May 2008 23:27:28 +0000 Subject: [PATCH] ok we have hourly rollup --- .../mysql/accounting_storage_mysql.c | 1 + .../accounting_storage/mysql/mysql_rollup.c | 345 ++++++++++++------ 2 files changed, 226 insertions(+), 120 deletions(-) diff --git a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c index 669bf675634..52bed03a963 100644 --- a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c +++ b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c @@ -4527,6 +4527,7 @@ extern int acct_storage_p_roll_usage(mysql_conn_t *mysql_conn) // last_hour = 1211403599; // last_hour = 1206946800; // last_day = 1207033199; +// last_day = 1197033199; // last_month = 1204358399; if(!localtime_r(&last_hour, &start_tm)) { diff --git a/src/plugins/accounting_storage/mysql/mysql_rollup.c b/src/plugins/accounting_storage/mysql/mysql_rollup.c index 09f9bb0bd38..58ee6a5afa9 100644 --- a/src/plugins/accounting_storage/mysql/mysql_rollup.c +++ b/src/plugins/accounting_storage/mysql/mysql_rollup.c @@ -49,6 +49,7 @@ typedef struct { typedef struct { char *name; + int total_time; int a_cpu; int cpu_count; int d_cpu; @@ -79,8 +80,10 @@ extern void _destroy_local_cluster_usage(void *object) extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn, time_t start, time_t end) { + int rc = SLURM_SUCCESS; int add_sec = 3600; int i=0; + time_t now = time(NULL); time_t curr_start = start; time_t curr_end = curr_start + add_sec; char *query = NULL; @@ -174,8 +177,8 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn, // first get the events during this time query = xstrdup_printf("select %s from %s where " "(period_start < %d " - "&& period_end >= %d) " - "|| period_end = 0 " + "&& (period_end >= %d " + "|| period_end = 0)) " "order by node_name, period_start", event_str, event_table, curr_end, curr_start); @@ -196,17 +199,47 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn, if(row_start < curr_start) row_start = curr_start; - if(!row_end) + if(!row_end || row_end > curr_end) row_end = curr_end; + /* Don't worry about it if the time is less + * than 1 second. + */ + if((row_end - row_start) < 1) + continue; + if(!row[EVENT_REQ_NAME][0]) { - c_usage = - xmalloc(sizeof(local_cluster_usage_t)); - c_usage->name = xstrdup(row[EVENT_REQ_CLUSTER]); - c_usage->cpu_count = row_cpu; - c_usage->start = row_start; - c_usage->end = row_end; - list_append(cluster_usage_list, c_usage); + list_iterator_reset(c_itr); + while((c_usage = list_next(c_itr))) { + if(!strcmp(c_usage->name, + row[EVENT_REQ_CLUSTER])) { + break; + } + } + /* if the cpu count changes we will + * only care about the last cpu count but + * we will keep a total of the time for + * all cpus to get the correct cpu time + * for the entire period. + */ + if(!c_usage) { + c_usage = xmalloc( + sizeof(local_cluster_usage_t)); + c_usage->name = + xstrdup(row[EVENT_REQ_CLUSTER]); + c_usage->cpu_count = row_cpu; + c_usage->total_time = + (row_end - row_start) * row_cpu; + c_usage->start = row_start; + c_usage->end = row_end; + list_append(cluster_usage_list, + c_usage); + } else { + c_usage->cpu_count = row_cpu; + c_usage->total_time += + (row_end - row_start) * row_cpu; + c_usage->end = row_end; + } continue; } @@ -236,10 +269,7 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn, row_cpu); c_usage->d_cpu += seconds * row_cpu; - /* don't break here just - incase the cpu count changed during - this time period. - */ + break; } } } @@ -247,12 +277,11 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn, query = xstrdup_printf("select %s from %s as t1, " "%s as t2 where " - "((eligible < %d && end >= %d) " - "|| end = 0 || start = 0) " - "&& associd=t2.id " + "(eligible < %d && (end >= %d " + "|| end = 0)) && associd=t2.id " "order by associd, eligible", job_str, job_table, assoc_table, - curr_end, curr_start); + curr_end, curr_start, curr_start); debug3("%d query\n%s", mysql_conn->conn, query); if(!(result = mysql_db_query_ret( @@ -262,23 +291,23 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn, } xfree(query); - while((row = mysql_fetch_row(result))) { - int job_id = atoi(row[JOB_REQ_ASSOCID]); + int job_id = atoi(row[JOB_REQ_JOBID]); int assoc_id = atoi(row[JOB_REQ_ASSOCID]); int row_eligible = atoi(row[JOB_REQ_ELG]); int row_start = atoi(row[JOB_REQ_START]); int row_end = atoi(row[JOB_REQ_END]); int row_acpu = atoi(row[JOB_REQ_ACPU]); int row_rcpu = atoi(row[JOB_REQ_RCPU]); - MYSQL_RES *result2 = NULL; - MYSQL_ROW row2; - + seconds = 0; + if(row_start && (row_start < curr_start)) row_start = curr_start; + if(!row_start && row_end) row_start = row_end; - if(!row_end) + + if(!row_end || row_end > curr_end) row_end = curr_end; if(last_id != assoc_id) { @@ -291,16 +320,18 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn, if(!row_start || ((row_end - row_start) < 1)) - continue; + goto calc_cluster; seconds = (row_end - row_start); if(row[JOB_REQ_SUSPENDED]) { + MYSQL_RES *result2 = NULL; + MYSQL_ROW row2; /* get the suspended time for this job */ query = xstrdup_printf( "select %s from %s where " - "((start < %d && end >= %d) " - "|| end = 0) && id=%s " + "(start < %d && (end >= %d " + "|| end = 0)) && id=%s " "order by start", suspend_str, suspend_table, curr_end, curr_start, @@ -316,9 +347,9 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn, xfree(query); while((row2 = mysql_fetch_row(result2))) { int local_start = - atoi(row[SUSPEND_REQ_START]); + atoi(row2[SUSPEND_REQ_START]); int local_end = - atoi(row[SUSPEND_REQ_END]); + atoi(row2[SUSPEND_REQ_END]); if(!local_start) continue; @@ -333,152 +364,165 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn, seconds -= (local_end - local_start); } + mysql_free_result(result2); + } if(seconds < 1) { debug("This job (%u) was suspended " "the entire hour", job_id); - if(result2) - mysql_free_result(result2); continue; } + + a_usage->a_cpu += seconds * row_acpu; - if(!row[JOB_REQ_CLUSTER]) { - if(result2) - mysql_free_result(result2); + calc_cluster: + if(!row[JOB_REQ_CLUSTER]) continue; - } + list_iterator_reset(c_itr); while((c_usage = list_next(c_itr))) { if(!strcmp(c_usage->name, row[JOB_REQ_CLUSTER])) { - int local_start = row_start; - int local_end = row_end; - if(!local_start) + if(!row_start || seconds < 1) goto calc_resv; - if(c_usage->start > local_start) - local_start = c_usage->start; - if(c_usage->end < local_end) - local_end = c_usage->end; - - if((local_end - local_start) < 1) - goto calc_resv; - - seconds = (local_end - local_start); - - if(result2) { - mysql_data_seek(result2, 0); - while((row2 = - mysql_fetch_row(result2) - )) { - int suspend_start = - atoi(row[SUSPEND_REQ_START]); - int suspend_end = - atoi(row[SUSPEND_REQ_END]); - - if(!suspend_start) - continue; - - if(c_usage->start - > suspend_start) - suspend_start = - c_usage->start; - if(c_usage->end - < suspend_end) - suspend_end = - c_usage->end; - - if((suspend_end - - suspend_start) - < 1) - continue; - - seconds -= - (suspend_end - - suspend_start); - } - - if(seconds < 1) { - debug("This job (%u) " - "was suspended " - "the entire " - "cluster time", - job_id); - continue; - } - } - info("%d assoc %d adds (%d)(%d-%d) * %d = %d " "to %d", job_id, assoc_id, seconds, - local_end, local_start, + row_end, row_start, row_acpu, seconds * row_acpu, row_acpu); + c_usage->a_cpu += seconds * row_acpu; + calc_resv: /* now reserved time */ if(row_start < c_usage->start) continue; - local_start = row_eligible; - local_end = row_start; - if(c_usage->start > local_start) - local_start = c_usage->start; - if(c_usage->end < local_end) - local_end = c_usage->end; - - if((local_end - local_start) < 1) + row_start = row_eligible; + row_end = row_start; + if(c_usage->start > row_start) + row_start = c_usage->start; + if(c_usage->end < row_end) + row_end = c_usage->end; + + if((row_end - row_start) < 1) continue; - seconds = (local_end - local_start); + seconds = (row_end - row_start); info("%d assoc %d reserved (%d)(%d-%d) * %d = %d " "to %d", job_id, assoc_id, seconds, - local_end, local_start, + row_end, row_start, row_rcpu, seconds * row_rcpu, row_rcpu); c_usage->r_cpu += seconds * row_rcpu; - /* don't break here just - incase the cpu count changed during - this time period. - */ + break; } } - if(result2) - mysql_free_result(result2); } mysql_free_result(result); list_iterator_reset(c_itr); + while((c_usage = list_next(c_itr))) { - int total_time = (curr_end - curr_start) - * c_usage->cpu_count; - - c_usage->i_cpu = total_time - c_usage->a_cpu - + c_usage->i_cpu = c_usage->total_time - c_usage->a_cpu - c_usage->d_cpu - c_usage->r_cpu; + /* sanity check just to make sure we have a + * legitimate time after we calulated + * idle/reserved time + */ + if(c_usage->i_cpu < 0) { c_usage->r_cpu += c_usage->i_cpu; c_usage->i_cpu = 0; if(c_usage->r_cpu < 0) c_usage->r_cpu = 0; } - + info("cluster %s(%u) down %u alloc %u " - "resv %u idle %u total= %u from %s", c_usage->name, + "resv %u idle %u total= %u = %u from %s", + c_usage->name, c_usage->cpu_count, c_usage->d_cpu, c_usage->a_cpu, c_usage->r_cpu, c_usage->i_cpu, c_usage->d_cpu + c_usage->a_cpu + c_usage->r_cpu + c_usage->i_cpu, + c_usage->total_time, ctime(&c_usage->start)); info("to %s", ctime(&c_usage->end)); + if(query) { + xstrfmtcat(query, + ", (%d, %d, '%s', %d, %u, " + "%u, %u, %u, %u)", + now, now, + c_usage->name, c_usage->start, + c_usage->cpu_count, c_usage->a_cpu, + c_usage->d_cpu, c_usage->i_cpu, + c_usage->r_cpu); + } else { + xstrfmtcat(query, + "insert into %s (creation_time, " + "mod_time, cluster, period_start, " + "cpu_count, alloc_cpu_secs, " + "down_cpu_secs, idle_cpu_secs, " + "resv_cpu_secs) values " + "(%d, %d, '%s', %d, %u, " + "%u, %u, %u, %u)", + cluster_hour_table, now, now, + c_usage->name, c_usage->start, + c_usage->cpu_count, c_usage->a_cpu, + c_usage->d_cpu, c_usage->i_cpu, + c_usage->r_cpu); + } + } + if(query) { + rc = mysql_db_query(mysql_conn->acct_mysql_db, query); + xfree(query); + if(rc != SLURM_SUCCESS) { + error("Couldn't add cluster hour rollup"); + goto end_it; + } + } + + list_iterator_reset(a_itr); + while((a_usage = list_next(a_itr))) { + info("association (%u) alloc %u", + a_usage->assoc_id, + a_usage->a_cpu); + if(query) { + xstrfmtcat(query, + ", (%d, %d, '%u', %d, %u, " + "%u, %u, %u, %u)", + now, now, + a_usage->assoc_id, curr_start, + a_usage->a_cpu); + } else { + xstrfmtcat(query, + "insert into %s (creation_time, " + "mod_time, id, period_start, " + "alloc_cpu_secs) values " + "(%d, %d, %u, %d, %u)", + assoc_hour_table, now, now, + a_usage->assoc_id, curr_start, + a_usage->a_cpu); + } + } + if(query) { + rc = mysql_db_query(mysql_conn->acct_mysql_db, query); + xfree(query); + if(rc != SLURM_SUCCESS) { + error("Couldn't add assoc hour rollup"); + goto end_it; + } } list_flush(assoc_usage_list); list_flush(cluster_usage_list); @@ -486,6 +530,8 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn, curr_end = curr_start + add_sec; debug3("curr hour is now %d-%d", curr_start, curr_end); } +end_it: + xfree(suspend_str); xfree(event_str); xfree(job_str); list_iterator_destroy(a_itr); @@ -495,22 +541,79 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn, list_destroy(cluster_usage_list); /* info("stop start %s", ctime(&curr_start)); */ /* info("stop end %s", ctime(&curr_end)); */ - return SLURM_SUCCESS; + return rc; } extern int mysql_daily_rollup(mysql_conn_t *mysql_conn, time_t start, time_t end) { - int add_sec = 86400; + /* can't just add 86400 since daylight savings starts and ends every + * once in a while + */ + int rc = SLURM_SUCCESS; + struct tm start_tm; time_t curr_start = start; - time_t curr_end = curr_start + add_sec; + time_t curr_end; + time_t now = time(NULL); + char *query = NULL; -/* info("begin start %s", ctime(&curr_start)); */ -/* info("begin end %s", ctime(&curr_end)); */ + if(!localtime_r(&curr_start, &start_tm)) { + error("Couldn't get localtime from day start %d", curr_start); + return SLURM_ERROR; + } + start_tm.tm_sec = 0; + start_tm.tm_min = 0; + start_tm.tm_hour = 0; + start_tm.tm_mday++; + start_tm.tm_isdst = -1; + curr_end = mktime(&start_tm); + + info("begin start %s", ctime(&curr_start)); + info("begin end %s", ctime(&curr_end)); while(curr_start < end) { + query = xstrdup_printf( + "insert into %s (creation_time, mod_time, id, " + "period_start, alloc_cpu_secs) select %d, %d, id, " + "%d, SUM(alloc_cpu_secs) from %s where " + "(period_start < %d && period_start >= %d) " + "group by id;", + assoc_day_table, now, now, curr_start, + assoc_hour_table, + curr_end, curr_start); + xstrfmtcat(query, + "insert into %s (creation_time, " + "mod_time, cluster, period_start, cpu_count, " + "alloc_cpu_secs, down_cpu_secs, idle_cpu_secs, " + "resv_cpu_secs) select %d, %d, cluster, " + "%d, MAX(cpu_count), SUM(alloc_cpu_secs), " + "SUM(down_cpu_secs), SUM(idle_cpu_secs), " + "SUM(resv_cpu_secs) from %s where " + "(period_start < %d && period_start >= %d) " + "group by cluster;", + cluster_day_table, now, now, curr_start, + cluster_hour_table, + curr_end, curr_start); + //rc = mysql_db_query(mysql_conn->acct_mysql_db, query); + xfree(query); + if(rc != SLURM_SUCCESS) { + error("Couldn't add day rollup"); + return SLURM_ERROR; + } curr_start = curr_end; - curr_end = curr_start + add_sec; + if(!localtime_r(&curr_start, &start_tm)) { + error("Couldn't get localtime from day start %d", + curr_start); + return SLURM_ERROR; + } + start_tm.tm_sec = 0; + start_tm.tm_min = 0; + start_tm.tm_hour = 0; + start_tm.tm_mday++; + start_tm.tm_isdst = -1; + curr_end = mktime(&start_tm); debug3("curr day is now %d-%d", curr_start, curr_end); + info("stop start %s", ctime(&curr_start)); + info("stop end %s", ctime(&curr_end)); } /* info("stop start %s", ctime(&curr_start)); */ /* info("stop end %s", ctime(&curr_end)); */ @@ -530,7 +633,7 @@ extern int mysql_monthly_rollup(mysql_conn_t *mysql_conn, error("Couldn't get localtime from month start %d", curr_start); return SLURM_ERROR; } - start_tm.tm_sec = -1; + start_tm.tm_sec = 0; start_tm.tm_min = 0; start_tm.tm_hour = 0; start_tm.tm_mday = 1; @@ -541,6 +644,8 @@ extern int mysql_monthly_rollup(mysql_conn_t *mysql_conn, /* info("begin end %s", ctime(&curr_end)); */ while(curr_start < end) { + /* FIX ME: DO CALCULATIONS HERE */ + curr_start = curr_end; if(!localtime_r(&curr_start, &start_tm)) { error("Couldn't get localtime from month start %d", -- GitLab