Skip to content
This repository has been archived by the owner on Oct 25, 2022. It is now read-only.

Commit

Permalink
Set poolInfo expired to false when the expression is NULL.
Browse files Browse the repository at this point in the history
In case that the volume is freshly created and is being written to
currently, `lastwritten` is `NULL`, which propagates through the expiry
calculation formula, resulting in a boolean field being `NULL`.
This causes an error to be raised, which results in a log line:

Jun 30 23:29:24 backup1 bareos_exporter[21509]: time="2021-06-30T23:29:24Z" level=error msg="sql: Scan error on column index 4, name \"expired\": sql/driver: couldn't convert <nil> (<nil>) into type bool" method=PoolInfo

When an error occurs while fetching pool info, statistics about pools
are not exported to prometheus at all, which may result in missing data.

Fixes #9
  • Loading branch information
vierbergenlars committed Jul 20, 2021
1 parent e710498 commit 07673a0
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 2 deletions.
4 changes: 2 additions & 2 deletions dataaccess.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ var queries map[string]*sqlQueries = map[string]*sqlQueries{
LastJob: "SELECT JobStatus,JobBytes,JobFiles,JobErrors,StartTime,COALESCE(EndTime, NOW()) FROM Job WHERE Name = ? AND ClientId = ? AND FileSetId = ? ORDER BY StartTime DESC LIMIT 1",
LastSuccessfulJob: "SELECT JobStatus,JobBytes,JobFiles,JobErrors,StartTime,COALESCE(EndTime, NOW()) FROM Job WHERE Name = ? AND ClientId = ? AND FileSetId = ? AND JobStatus IN('T', 'W') ORDER BY StartTime DESC LIMIT 1",
LastSuccessfulFullJob: "SELECT JobStatus,JobBytes,JobFiles,JobErrors,StartTime,COALESCE(EndTime, NOW()) FROM Job WHERE Name = ? AND ClientId = ? AND FileSetId = ? AND JobStatus IN('T', 'W') AND Level = 'F' ORDER BY StartTime DESC LIMIT 1",
PoolInfo: "SELECT p.name, sum(m.volbytes) AS bytes, count(*) AS volumes, (not exists(select * from JobMedia jm where jm.mediaid = m.mediaid)) AS prunable, TIMESTAMPADD(SECOND, m.volretention, m.lastwritten) < NOW() AS expired FROM Media m LEFT JOIN Pool p ON m.poolid = p.poolid GROUP BY p.name, prunable, expired",
PoolInfo: "SELECT p.name, sum(m.volbytes) AS bytes, count(*) AS volumes, (not exists(select * from JobMedia jm where jm.mediaid = m.mediaid)) AS prunable, COALESCE(TIMESTAMPADD(SECOND, m.volretention, m.lastwritten) < NOW(), false) AS expired FROM Media m LEFT JOIN Pool p ON m.poolid = p.poolid GROUP BY p.name, prunable, expired",
JobStates: "SELECT JobStatus FROM Status",
},
"postgres": &sqlQueries{
JobList: "SELECT j.Name, j.Type, j.ClientId, j.FileSetId, COALESCE(c.Name, ''), COALESCE(f.FileSet, ''), COUNT(*), SUM(j.JobBytes), SUM(j.JobFiles) FROM job j LEFT JOIN client c ON c.ClientId = j.ClientId LEFT JOIN fileset f ON f.FileSetId = j.FileSetId GROUP BY j.Name, j.Type, j.ClientId, j.FileSetId, c.Name, f.FileSet HAVING MAX(j.SchedTime) >= $1",
LastJob: "SELECT JobStatus,JobBytes,JobFiles,JobErrors,StartTime::timestamptz,COALESCE(EndTime::timestamptz, NOW()) FROM job WHERE Name = $1 AND ClientId = $2 AND FileSetId = $3 ORDER BY StartTime DESC LIMIT 1",
LastSuccessfulJob: "SELECT JobStatus,JobBytes,JobFiles,JobErrors,StartTime::timestamptz,COALESCE(EndTime::timestamptz, NOW()) FROM job WHERE Name = $1 AND ClientId = $2 AND FileSetId = $3 AND JobStatus IN('T', 'W') ORDER BY StartTime DESC LIMIT 1",
LastSuccessfulFullJob: "SELECT JobStatus,JobBytes,JobFiles,JobErrors,StartTime::timestamptz,COALESCE(EndTime::timestamptz, NOW()) FROM job WHERE Name = $1 AND ClientId = $2 AND FileSetId = $3 AND JobStatus IN('T', 'W') AND Level = 'F' ORDER BY StartTime DESC LIMIT 1",
PoolInfo: "SELECT p.name, sum(m.volbytes) AS bytes, count(m) AS volumes, (not exists(select * from jobmedia jm where jm.mediaid = m.mediaid)) AS prunable, (m.lastwritten + (m.volretention * interval '1s')) < NOW() as expired FROM media m LEFT JOIN pool p ON m.poolid = p.poolid GROUP BY p.name, prunable, expired",
PoolInfo: "SELECT p.name, sum(m.volbytes) AS bytes, count(m) AS volumes, (not exists(select * from jobmedia jm where jm.mediaid = m.mediaid)) AS prunable, COALESCE((m.lastwritten + (m.volretention * interval '1s')) < NOW(), false) as expired FROM media m LEFT JOIN pool p ON m.poolid = p.poolid GROUP BY p.name, prunable, expired",
JobStates: "SELECT JobStatus FROM status",
},
}
Expand Down
5 changes: 5 additions & 0 deletions development/mysql/03-issue-9.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- Reproduction of https://github.com/vierbergenlars/bareos_exporter/issues/9

INSERT INTO Media (volumename, mediatype, firstwritten, lastwritten, labeldate, volstatus, poolid)
VALUES
('Pool1-0100', 'NULL', NOW() - interval 1 day + interval 30 second, NULL, NOW() - interval 1 day, 'Full', (SELECT poolid from Pool WHERE name = 'Pool1'));
5 changes: 5 additions & 0 deletions development/postgres/03-issue-9.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- Reproduction of https://github.com/vierbergenlars/bareos_exporter/issues/9

INSERT INTO public.media (volumename, mediatype, firstwritten, lastwritten, labeldate, volstatus, poolid)
VALUES
('Pool1-0100', 'NULL', NOW() - interval '1 day' + interval '30s', NULL, NOW() - interval '1 day', 'Full', (SELECT poolid from pool WHERE name = 'Pool1'));

0 comments on commit 07673a0

Please sign in to comment.