2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2017 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * Catalog DB header file
22 * Written by Kern E. Sibbald
24 * Anyone who accesses the database will need to include
32 Here is how database versions work.
34 While I am working on a new release with database changes, the
35 update scripts are in the src/cats directory under the names
36 update_xxx_tables.in. Most of the time, I make database updates
37 in one go and immediately update the version, but not always. If
38 there are going to be several updates as is the case with version
39 1.37, then I will often forgo changing the version until the last
40 update otherwise I will end up with too many versions and a lot
43 When I am pretty sure there will be no more updates, I will
44 change the version from 8 to 9 (in the present case), and when I
45 am 100% sure there will be no more changes, the update script
46 will be copied to the updatedb directory with the correct name
47 (in the present case 8 to 9).
50 /* Current database version number for all drivers */
51 #define BDB_VERSION 16
53 typedef void (DB_LIST_HANDLER)(void *, const char *);
54 typedef int (DB_RESULT_HANDLER)(void *, int, char **);
56 /* What kind of database we have */
59 SQL_TYPE_POSTGRESQL = 1,
64 /* What kind of driver we have */
66 SQL_DRIVER_TYPE_MYSQL = 0,
67 SQL_DRIVER_TYPE_POSTGRESQL = 1,
68 SQL_DRIVER_TYPE_SQLITE3 = 2
72 /* ==============================================================
74 * What follows are definitions that are used "globally" for all
75 * the different SQL engines and both inside and external to the
82 * Generic definition of a sql_row.
84 typedef char **SQL_ROW;
87 * Generic definition of a a sql_field.
89 typedef struct sql_field {
90 char *name; /* name of column */
91 int max_length; /* max length */
92 uint32_t type; /* type */
93 uint32_t flags; /* flags */
98 * Structure used when calling db_get_query_ids()
99 * allows the subroutine to return a list of ids.
101 class dbid_list : public SMARTALLOC {
103 DBId_t *DBId; /* array of DBIds */
104 char *PurgedFiles; /* Array of PurgedFile flags */
105 int num_ids; /* num of ids actually stored */
106 int max_ids; /* size of id array */
107 int num_seen; /* number of ids processed */
108 int tot_ids; /* total to process */
110 dbid_list(); /* in sql.c */
111 ~dbid_list(); /* in sql.c */
114 /* Job information passed to create job record and update
115 * job record at end of job. Note, although this record
116 * contains all the fields found in the Job database record,
117 * it also contains fields found in the JobMedia record.
122 char Job[MAX_NAME_LENGTH]; /* Job unique name */
123 char Name[MAX_NAME_LENGTH]; /* Job base name */
124 int JobType; /* actually char(1) */
125 int JobLevel; /* actually char(1) */
126 int JobStatus; /* actually char(1) */
127 DBId_t ClientId; /* Id of client */
128 DBId_t PoolId; /* Id of pool */
129 DBId_t FileSetId; /* Id of FileSet */
130 DBId_t PriorJobId; /* Id of migrated (prior) job */
131 time_t SchedTime; /* Time job scheduled */
132 time_t StartTime; /* Job start time */
133 time_t EndTime; /* Job termination time of orig job */
134 time_t RealEndTime; /* Job termination time of this job */
135 utime_t JobTDate; /* Backup time/date in seconds */
136 uint32_t VolSessionId;
137 uint32_t VolSessionTime;
140 uint32_t JobMissingFiles;
146 /* Note, FirstIndex, LastIndex, Start/End File and Block
147 * are only used in the JobMedia record.
149 uint32_t FirstIndex; /* First index this Volume */
150 uint32_t LastIndex; /* Last index this Volume */
156 char cSchedTime[MAX_TIME_LENGTH];
157 char cStartTime[MAX_TIME_LENGTH];
158 char cEndTime[MAX_TIME_LENGTH];
159 char cRealEndTime[MAX_TIME_LENGTH];
160 /* Extra stuff not in DB */
161 int order; /* 0 ASC, 1 DESC */
162 int limit; /* limit records to display */
164 uint32_t FileIndex; /* added during Verify */
166 int CorrNbJob; /* used by dbd_get_job_statistics() */
167 int CorrJobBytes; /* used by dbd_get_job_statistics() */
168 int CorrJobFiles; /* used by dbd_get_job_statistics() */
171 /* Job Media information used to create the media records
172 * for each Volume used for the job.
174 /* JobMedia record */
175 struct JOBMEDIA_DBR {
176 DBId_t JobMediaId; /* record id */
177 JobId_t JobId; /* JobId */
178 DBId_t MediaId; /* MediaId */
179 uint32_t FirstIndex; /* First index this Volume */
180 uint32_t LastIndex; /* Last index this Volume */
181 uint32_t StartFile; /* File for start of data */
182 uint32_t EndFile; /* End file on Volume */
183 uint32_t StartBlock; /* start block on tape */
184 uint32_t EndBlock; /* last block */
188 /* Volume Parameter structure */
190 char VolumeName[MAX_NAME_LENGTH]; /* Volume name */
191 char MediaType[MAX_NAME_LENGTH]; /* Media Type */
192 char Storage[MAX_NAME_LENGTH]; /* Storage name */
193 uint32_t VolIndex; /* Volume seqence no. */
194 uint32_t FirstIndex; /* First index this Volume */
195 uint32_t LastIndex; /* Last index this Volume */
196 int32_t Slot; /* Slot */
197 uint64_t StartAddr; /* Start address */
198 uint64_t EndAddr; /* End address */
199 int32_t InChanger; /* InChanger flag */
203 /* Attributes record -- NOT same as in database because
204 * in general, this "record" creates multiple database
205 * records (e.g. pathname, filename, fileattributes).
208 char *fname; /* full path & filename */
209 char *link; /* link if any */
210 char *attr; /* attributes statp */
230 uint32_t object_full_len;
231 uint32_t object_index;
232 int32_t object_compression;
237 DBId_t RestoreObjectId;
241 /* File record -- same format as database */
251 char Digest[BASE64_SIZE(CRYPTO_DIGEST_MAX_SIZE)];
252 int DigestType; /* NO_SIG/MD5_SIG/SHA1_SIG */
255 /* Pool record -- same format as database */
258 char Name[MAX_NAME_LENGTH]; /* Pool name */
259 uint32_t NumVols; /* total number of volumes */
260 uint32_t MaxVols; /* max allowed volumes */
261 int32_t LabelType; /* Bacula/ANSI/IBM */
262 int32_t UseOnce; /* set to use once only */
263 int32_t UseCatalog; /* set to use catalog */
264 int32_t AcceptAnyVolume; /* set to accept any volume sequence */
265 int32_t AutoPrune; /* set to prune automatically */
266 int32_t Recycle; /* default Vol recycle flag */
267 uint32_t ActionOnPurge; /* action on purge, e.g. truncate the disk volume */
268 utime_t VolRetention; /* retention period in seconds */
269 utime_t CacheRetention; /* cache retention period in seconds */
270 utime_t VolUseDuration; /* time in secs volume can be used */
271 uint32_t MaxVolJobs; /* Max Jobs on Volume */
272 uint32_t MaxVolFiles; /* Max files on Volume */
273 uint64_t MaxVolBytes; /* Max bytes on Volume */
274 DBId_t RecyclePoolId; /* RecyclePool destination when media is purged */
275 DBId_t ScratchPoolId; /* ScratchPool source when media is needed */
276 char PoolType[MAX_NAME_LENGTH];
277 char LabelFormat[MAX_NAME_LENGTH];
278 /* Extra stuff not in DB */
285 char Name[MAX_NAME_LENGTH]; /* Device name */
286 DBId_t MediaTypeId; /* MediaType */
287 DBId_t StorageId; /* Storage id if autochanger */
288 uint32_t DevMounts; /* Number of times mounted */
289 uint32_t DevErrors; /* Number of read/write errors */
290 uint64_t DevReadBytes; /* Number of bytes read */
291 uint64_t DevWriteBytes; /* Number of bytew written */
292 uint64_t DevReadTime; /* time spent reading volume */
293 uint64_t DevWriteTime; /* time spent writing volume */
294 uint64_t DevReadTimeSincCleaning; /* read time since cleaning */
295 uint64_t DevWriteTimeSincCleaning; /* write time since cleaning */
296 time_t CleaningDate; /* time last cleaned */
297 utime_t CleaningPeriod; /* time between cleanings */
303 char Name[MAX_NAME_LENGTH]; /* Device name */
304 int AutoChanger; /* Set if autochanger */
306 /* Not in database */
307 bool created; /* set if created by db_create ... */
310 class MEDIATYPE_DBR {
313 char MediaType[MAX_NAME_LENGTH]; /* MediaType string */
314 int ReadOnly; /* Set if read-only */
317 /* Media record -- same as the database */
320 MEDIA_DBR() { memset(this, 0, sizeof(MEDIA_DBR)); };
322 void clear() { memset(this, 0, sizeof(MEDIA_DBR)); };
323 void copy(MEDIA_DBR *omr) { memcpy(this, omr, sizeof(MEDIA_DBR)); sid_group = NULL; };
325 DBId_t MediaId; /* Unique volume id */
326 char VolumeName[MAX_NAME_LENGTH]; /* Volume name */
327 char MediaType[MAX_NAME_LENGTH]; /* Media type */
328 DBId_t PoolId; /* Pool id */
329 time_t FirstWritten; /* Time Volume first written this usage */
330 time_t LastWritten; /* Time Volume last written */
331 time_t LabelDate; /* Date/Time Volume labeled */
332 time_t InitialWrite; /* Date/Time Volume first written */
333 int32_t LabelType; /* Label (Bacula/ANSI/IBM) */
334 uint32_t VolJobs; /* number of jobs on this medium */
335 uint32_t VolFiles; /* Number of files */
336 uint32_t VolBlocks; /* Number of blocks */
337 uint32_t VolParts; /* Number of cache parts */
338 uint32_t VolCloudParts; /* Number of cloud parts */
339 uint32_t VolMounts; /* Number of times mounted */
340 uint32_t VolErrors; /* Number of read/write errors */
341 uint64_t VolWrites; /* Number of writes */
342 uint64_t VolReads; /* Number of reads */
343 uint64_t VolBytes; /* Number of bytes written */
344 uint64_t VolABytes; /* Size of aligned volume */
345 uint64_t VolHoleBytes; /* The size of Holes */
346 uint32_t VolHoles; /* Number of holes */
347 uint32_t VolType; /* Device type of where Volume labeled */
348 uint64_t MaxVolBytes; /* Max bytes to write to Volume */
349 uint64_t VolCapacityBytes; /* capacity estimate */
350 uint64_t LastPartBytes; /* Bytes in last part */
351 uint64_t VolReadTime; /* time spent reading volume */
352 uint64_t VolWriteTime; /* time spent writing volume */
353 utime_t VolRetention; /* Volume retention in seconds */
354 utime_t CacheRetention; /* Cache retention period in second */
355 utime_t VolUseDuration; /* time in secs volume can be used */
356 uint32_t ActionOnPurge; /* action on purge, e.g. truncate the disk volume */
357 uint32_t MaxVolJobs; /* Max Jobs on Volume */
358 uint32_t MaxVolFiles; /* Max files on Volume */
359 int32_t Recycle; /* recycle yes/no */
360 int32_t Slot; /* slot in changer */
361 int32_t Enabled; /* 0=disabled, 1=enabled, 2=archived */
362 int32_t InChanger; /* Volume currently in changer */
363 DBId_t StorageId; /* Storage record Id */
364 uint32_t EndFile; /* Last file on volume */
365 uint32_t EndBlock; /* Last block on volume */
366 uint32_t RecycleCount; /* Number of times recycled */
367 char VolStatus[20]; /* Volume status */
368 DBId_t DeviceId; /* Device where Vol last written */
369 DBId_t LocationId; /* Where Volume is -- user defined */
370 DBId_t ScratchPoolId; /* Where to move if scratch */
371 DBId_t RecyclePoolId; /* Where to move when recycled */
372 /* Extra stuff not in DB */
373 faddr_t rec_addr; /* found record address */
374 /* Since the database returns times as strings, this is how we pass
377 char cFirstWritten[MAX_TIME_LENGTH]; /* FirstWritten returned from DB */
378 char cLastWritten[MAX_TIME_LENGTH]; /* LastWritten returned from DB */
379 char cLabelDate[MAX_TIME_LENGTH]; /* LabelData returned from DB */
380 char cInitialWrite[MAX_TIME_LENGTH]; /* InitialWrite returned from DB */
381 char *exclude_list; /* Optionnal exclude list for db_find_next_volume() */
382 char *sid_group; /* Storageid group string */
383 char sid[30]; /* edited StorageId */
384 bool set_first_written;
388 /* Client record -- same as the database */
390 DBId_t ClientId; /* Unique Client id */
392 utime_t FileRetention;
393 utime_t JobRetention;
394 char Name[MAX_NAME_LENGTH]; /* Client name */
395 char Uname[256]; /* Uname for client */
398 /* Counter record as in database */
400 char Counter[MAX_NAME_LENGTH];
403 int32_t CurrentValue;
404 char WrapCounter[MAX_NAME_LENGTH];
408 /* FileSet record -- same as the database */
410 DBId_t FileSetId; /* Unique FileSet id */
411 char FileSet[MAX_NAME_LENGTH]; /* FileSet name */
412 char MD5[50]; /* MD5 signature of include/exclude */
413 time_t CreateTime; /* date created */
415 * This is where we return CreateTime
417 char cCreateTime[MAX_TIME_LENGTH]; /* CreateTime as returned from DB */
418 /* Not in DB but returned by db_create_fileset() */
419 bool created; /* set when record newly created */
425 memset(this, 0, sizeof(SNAPSHOT_DBR));
430 void debug(int level) {
431 Dmsg8(DT_SNAPSHOT|level,
440 Name, NPRT(Volume), NPRT(Device), SnapshotId,
441 FileSet, CreateDate, Client, Type);
443 char *as_arg(POOLMEM **out) {
454 Mmsg(out, "name=%s volume=%s device=%s tdate=%d type=%s",
455 Name, NPRTB(Volume), NPRTB(Device), CreateTDate, Type);
460 unbash_spaces(Volume);
463 unbash_spaces(Device);
478 errmsg = Volume = Device = NULL;
480 need_to_free = false;
482 bool need_to_free; /* Need to free the internal memory */
483 /* Used when searching snapshots */
484 char created_after[MAX_TIME_LENGTH];
485 char created_before[MAX_TIME_LENGTH];
486 bool expired; /* Look for CreateTDate > (NOW - Retention) */
487 bool sorted_client; /* Results sorted by Client, SnapshotId */
488 int status; /* Status of the snapshot */
490 DBId_t SnapshotId; /* Unique Snapshot ID */
491 DBId_t JobId; /* Related JobId */
492 DBId_t FileSetId; /* FileSetId if any */
493 DBId_t ClientId; /* From which client this snapshot comes */
494 char Name[MAX_NAME_LENGTH]; /* Snapshot Name */
495 char FileSet[MAX_NAME_LENGTH];/* FileSet name if any */
496 char Client[MAX_NAME_LENGTH]; /* Client name */
497 char Type[MAX_NAME_LENGTH]; /* zfs, btrfs, lvm, netapp, */
498 char Comment[MAX_NAME_LENGTH];/* Comment */
499 char CreateDate[MAX_TIME_LENGTH]; /* Create date as string */
500 time_t CreateTDate; /* Create TDate (in sec, since epoch) */
501 char *Volume; /* Volume taken in snapshot */
502 char *Device; /* Device, Pool, Directory, ... */
503 char *errmsg; /* Error associated with a snapshot */
504 utime_t Retention; /* Number of second before pruning the snapshot */
505 uint64_t Size; /* Snapshot Size */
508 /* Call back context for getting a 32/64 bit value from the database */
511 int64_t value; /* value returned */
512 int count; /* number of values seen */
514 db_int64_ctx() : value(0), count(0) {};
517 db_int64_ctx(const db_int64_ctx&); /* prohibit pass by value */
518 db_int64_ctx &operator=(const db_int64_ctx&); /* prohibit class assignment */
521 /* Call back context for getting a list of comma separated strings from the
526 POOLMEM *list; /* list */
527 int count; /* number of values seen */
529 db_list_ctx() { list = get_pool_memory(PM_FNAME); reset(); }
530 ~db_list_ctx() { free_pool_memory(list); list = NULL; }
531 void reset() { *list = 0; count = 0;}
532 void add(const db_list_ctx &str) {
535 pm_strcat(list, ",");
537 pm_strcat(list, str.list);
541 void add(const char *str) {
543 pm_strcat(list, ",");
545 pm_strcat(list, str);
549 db_list_ctx(const db_list_ctx&); /* prohibit pass by value */
550 db_list_ctx &operator=(const db_list_ctx&); /* prohibit class assignment */
553 /* sql_query flags */
554 #define QF_STORE_RESULT 0x01
558 HORZ_LIST, /* list */
559 VERT_LIST, /* llist */
560 ARG_LIST, /* key1=v1 key2=v2 key3=v3 */
568 #include "sql_cmds.h"
571 /* Object used in db_list_xxx function */
574 char line[256]; /* Used to print last dash line */
577 e_list_type type; /* Vertical/Horizontal */
578 DB_LIST_HANDLER *send; /* send data back */
579 bool once; /* Used to print header one time */
580 void *ctx; /* send() user argument */
595 LIST_CTX(JCR *j, BDB *m, DB_LIST_HANDLER *h, void *c, e_list_type t) {
607 /* Functions exported by sql.c for use within the cats directory. */
608 int list_result(void *vctx, int cols, char **row);
609 int list_result(JCR *jcr, BDB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type);
610 int get_sql_record_max(JCR *jcr, BDB *mdb);
611 void list_dashes(BDB *mdb, DB_LIST_HANDLER *send, void *ctx);
613 void print_dashes(BDB *mdb);
614 void print_result(BDB *mdb);
615 int QueryDB(const char *file, int line, JCR *jcr, BDB *db, char *select_cmd);
616 int InsertDB(const char *file, int line, JCR *jcr, BDB *db, char *select_cmd);
617 int DeleteDB(const char *file, int line, JCR *jcr, BDB *db, char *delete_cmd);
618 void split_path_and_file(JCR *jcr, BDB *mdb, const char *fname);
620 #endif /* __CATS_H_ */