INDEX (Name(128))
);
+-- Create a table like Job for long term statistics
+CREATE TABLE JobStat (LIKE Job);
CREATE TABLE Location (
LocationId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
CREATE INDEX job_name_idx on job (name);
+-- Create a table like Job for long term statistics
+CREATE TABLE jobstat (LIKE job);
+
CREATE TABLE Location (
LocationId serial not null,
Location text not null,
);
CREATE INDEX inx6 ON Job (Name);
+-- Create a table like Job for long term statistics
+CREATE TABLE JobStat (LIKE Job);
+
CREATE TABLE Location (
LocationId INTEGER,
Location TEXT NOT NULL,
);
CREATE INDEX inx6 ON Job (Name);
+-- Create a table like Job for long term statistics
+CREATE TABLE JobStat (LIKE Job);
+
CREATE TABLE Location (
LocationId INTEGER,
Location TEXT NOT NULL,
/* sql_update.c */
bool db_update_job_start_record(JCR *jcr, B_DB *db, JOB_DBR *jr);
-int db_update_job_end_record(JCR *jcr, B_DB *db, JOB_DBR *jr);
+int db_update_job_end_record(JCR *jcr, B_DB *db, JOB_DBR *jr, bool stats_enabled);
int db_update_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr);
int db_update_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pr);
bool db_update_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr);
bool
db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
{
- bool ok = true;;
+ bool ok = true;
int count;
char ed1[50], ed2[50];
return ok;
}
-
-
/* Create Unique Pool record
* Returns: false on failure
* true on success
* 1 on success
*/
int
-db_update_job_end_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
+db_update_job_end_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, bool stats_enabled)
{
char dt[MAX_TIME_LENGTH];
char rdt[MAX_TIME_LENGTH];
edit_int64(jr->JobId, ed3));
stat = UPDATE_DB(jcr, mdb, mdb->cmd);
+
+ if (stat && stats_enabled) {
+ Mmsg(mdb->cmd,
+ "INSERT INTO JobStat (SELECT * FROM Job WHERE JobId=%s)",
+ edit_int64(jr->JobId, ed3));
+ INSERT_DB(jcr, mdb, mdb->cmd); /* TODO: get a message ? */
+ }
db_unlock(mdb);
return stat;
}
-
/*
* Update Client record
* Returns: 0 on failure
{"tlskey", store_dir, ITEM(res_dir.tls_keyfile), 0, 0, 0},
{"tlsdhfile", store_dir, ITEM(res_dir.tls_dhfile), 0, 0, 0},
{"tlsallowedcn", store_alist_str, ITEM(res_dir.tls_allowed_cns), 0, 0, 0},
+ {"statisticsretention", store_time, ITEM(res_dir.stats_retention), 0, ITEM_DEFAULT, 60*60*24*31*12*5},
{NULL, NULL, {0}, 0, 0, 0}
};
{"selectionpattern", store_str, ITEM(res_job.selection_pattern), 0, 0, 0},
{"runscript", store_runscript, ITEM(res_job.RunScripts), 0, ITEM_NO_EQUALS, 0},
{"selectiontype", store_migtype, ITEM(res_job.selection_type), 0, 0, 0},
+ {"usestatistics", store_bool, ITEM(res_job.stats_enabled), 0, 0, 0},
{"accurate", store_bool, ITEM(res_job.accurate), 0,0,0},
{"allowduplicatejobs", store_bool, ITEM(res_job.AllowDuplicateJobs), 0, ITEM_DEFAULT, false},
{"allowhigherduplicates", store_bool, ITEM(res_job.AllowHigherDuplicates), 0, ITEM_DEFAULT, true},
if (res->res_job.RegexWhere) {
sendit(sock, _(" --> RegexWhere=%s\n"), NPRT(res->res_job.RegexWhere));
}
+ if (res->res_job.stats_enabled) {
+ sendit(sock, _(" --> StatsEnabled=%d\n"), res->res_job.stats_enabled);
+ }
if (res->res_job.RestoreBootstrap) {
sendit(sock, _(" --> Bootstrap=%s\n"), NPRT(res->res_job.RestoreBootstrap));
}
bool tls_enable; /* Enable TLS */
bool tls_require; /* Require TLS */
bool tls_verify_peer; /* TLS Verify Client Certificate */
+ utime_t stats_retention; /* Stats retention period in seconds */
/* Methods */
char *name() const;
bool write_part_after_job; /* Set to write part after job in SD */
bool enabled; /* Set if job enabled */
bool OptimizeJobScheduling; /* Set if we should optimize Job scheduling */
+ bool stats_enabled; /* Keep job records in a table for long term statistics */
bool accurate; /* Set if it is an accurate backup job */
bool AllowDuplicateJobs; /* Allow duplicate jobs */
bool AllowHigherDuplicates; /* Permit Higher Level */
jcr->jr.VolSessionId = jcr->VolSessionId;
jcr->jr.VolSessionTime = jcr->VolSessionTime;
jcr->jr.JobErrors = jcr->Errors;
- if (!db_update_job_end_record(jcr, jcr->db, &jcr->jr)) {
+ if (!db_update_job_end_record(jcr, jcr->db, &jcr->jr, jcr->job->stats_enabled)) {
Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"),
db_strerror(jcr->db));
}
* prune files (from) client=xxx
* prune jobs (from) client=xxx
* prune volume=xxx
+ * prune stats
*/
int prunecmd(UAContext *ua, const char *cmd)
{
NT_("Files"),
NT_("Jobs"),
NT_("Volume"),
+ NT_("Stats"),
NULL};
if (!open_client_db(ua)) {
/* First search args */
kw = find_arg_keyword(ua, keywords);
- if (kw < 0 || kw > 2) {
+ if (kw < 0 || kw > 3) {
/* no args, so ask user */
kw = do_keyword_prompt(ua, _("Choose item to prune"), keywords);
}
}
prune_volume(ua, &mr);
return true;
+ case 3: /* prune stats */
+ /* TODO: prune JobStat table */
+ return true;
default:
break;
}
bool unlink_bsr; /* Unlink bsr file created */
bool VSS; /* VSS used by FD */
bool Encrypt; /* Encryption used by FD */
+ bool stats_enabled; /* Keep all job records in a table for long term statistics */
#endif /* DIRECTOR_DAEMON */
jr.VolSessionTime = mjcr->VolSessionTime;
jr.JobTDate = (utime_t)mjcr->start_time;
jr.ClientId = mjcr->ClientId;
- if (!db_update_job_end_record(bjcr, db, &jr)) {
+ if (!db_update_job_end_record(bjcr, db, &jr, false)) {
Pmsg1(0, _("Could not update job record. ERR=%s\n"), db_strerror(db));
}
mjcr->read_dcr = NULL;
return 1;
}
- if (!db_update_job_end_record(bjcr, db, jr)) {
+ if (!db_update_job_end_record(bjcr, db, jr, false)) {
Pmsg2(0, _("Could not update JobId=%u record. ERR=%s\n"), jr->JobId, db_strerror(db));
free_jcr(mjcr);
return 0;
Improved status commands for Bat
Spooling/despooling status
Implement ftruncate for NFS devices
+Add long term statistic job table
General:
20Mar08
+ebl Apply jobstat patch for long term statistics. Have to implement
+ purge stats command and upgrade scripts.
kes Fix mtx-changer.in for broken Debian mt program.
19Mar08
kes Fix large number of JobMedia records reported by Eric Bollengier.