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 15
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 */
167 /* Job Media information used to create the media records
168 * for each Volume used for the job.
170 /* JobMedia record */
171 struct JOBMEDIA_DBR {
172 DBId_t JobMediaId; /* record id */
173 JobId_t JobId; /* JobId */
174 DBId_t MediaId; /* MediaId */
175 uint32_t FirstIndex; /* First index this Volume */
176 uint32_t LastIndex; /* Last index this Volume */
177 uint32_t StartFile; /* File for start of data */
178 uint32_t EndFile; /* End file on Volume */
179 uint32_t StartBlock; /* start block on tape */
180 uint32_t EndBlock; /* last block */
184 /* Volume Parameter structure */
186 char VolumeName[MAX_NAME_LENGTH]; /* Volume name */
187 char MediaType[MAX_NAME_LENGTH]; /* Media Type */
188 char Storage[MAX_NAME_LENGTH]; /* Storage name */
189 uint32_t VolIndex; /* Volume seqence no. */
190 uint32_t FirstIndex; /* First index this Volume */
191 uint32_t LastIndex; /* Last index this Volume */
192 int32_t Slot; /* Slot */
193 uint64_t StartAddr; /* Start address */
194 uint64_t EndAddr; /* End address */
195 int32_t InChanger; /* InChanger flag */
199 /* Attributes record -- NOT same as in database because
200 * in general, this "record" creates multiple database
201 * records (e.g. pathname, filename, fileattributes).
204 char *fname; /* full path & filename */
205 char *link; /* link if any */
206 char *attr; /* attributes statp */
226 uint32_t object_full_len;
227 uint32_t object_index;
228 int32_t object_compression;
233 DBId_t RestoreObjectId;
237 /* File record -- same format as database */
247 char Digest[BASE64_SIZE(CRYPTO_DIGEST_MAX_SIZE)];
248 int DigestType; /* NO_SIG/MD5_SIG/SHA1_SIG */
251 /* Pool record -- same format as database */
254 char Name[MAX_NAME_LENGTH]; /* Pool name */
255 uint32_t NumVols; /* total number of volumes */
256 uint32_t MaxVols; /* max allowed volumes */
257 int32_t LabelType; /* Bacula/ANSI/IBM */
258 int32_t UseOnce; /* set to use once only */
259 int32_t UseCatalog; /* set to use catalog */
260 int32_t AcceptAnyVolume; /* set to accept any volume sequence */
261 int32_t AutoPrune; /* set to prune automatically */
262 int32_t Recycle; /* default Vol recycle flag */
263 uint32_t ActionOnPurge; /* action on purge, e.g. truncate the disk volume */
264 utime_t VolRetention; /* retention period in seconds */
265 utime_t VolUseDuration; /* time in secs volume can be used */
266 uint32_t MaxVolJobs; /* Max Jobs on Volume */
267 uint32_t MaxVolFiles; /* Max files on Volume */
268 uint64_t MaxVolBytes; /* Max bytes on Volume */
269 DBId_t RecyclePoolId; /* RecyclePool destination when media is purged */
270 DBId_t ScratchPoolId; /* ScratchPool source when media is needed */
271 char PoolType[MAX_NAME_LENGTH];
272 char LabelFormat[MAX_NAME_LENGTH];
273 /* Extra stuff not in DB */
280 char Name[MAX_NAME_LENGTH]; /* Device name */
281 DBId_t MediaTypeId; /* MediaType */
282 DBId_t StorageId; /* Storage id if autochanger */
283 uint32_t DevMounts; /* Number of times mounted */
284 uint32_t DevErrors; /* Number of read/write errors */
285 uint64_t DevReadBytes; /* Number of bytes read */
286 uint64_t DevWriteBytes; /* Number of bytew written */
287 uint64_t DevReadTime; /* time spent reading volume */
288 uint64_t DevWriteTime; /* time spent writing volume */
289 uint64_t DevReadTimeSincCleaning; /* read time since cleaning */
290 uint64_t DevWriteTimeSincCleaning; /* write time since cleaning */
291 time_t CleaningDate; /* time last cleaned */
292 utime_t CleaningPeriod; /* time between cleanings */
298 char Name[MAX_NAME_LENGTH]; /* Device name */
299 int AutoChanger; /* Set if autochanger */
301 /* Not in database */
302 bool created; /* set if created by db_create ... */
305 class MEDIATYPE_DBR {
308 char MediaType[MAX_NAME_LENGTH]; /* MediaType string */
309 int ReadOnly; /* Set if read-only */
312 /* Media record -- same as the database */
315 MEDIA_DBR() { memset(this, 0, sizeof(MEDIA_DBR)); };
317 void clear() { memset(this, 0, sizeof(MEDIA_DBR)); };
318 void copy(MEDIA_DBR *omr) { memcpy(this, omr, sizeof(MEDIA_DBR)); };
320 DBId_t MediaId; /* Unique volume id */
321 char VolumeName[MAX_NAME_LENGTH]; /* Volume name */
322 char MediaType[MAX_NAME_LENGTH]; /* Media type */
323 DBId_t PoolId; /* Pool id */
324 time_t FirstWritten; /* Time Volume first written this usage */
325 time_t LastWritten; /* Time Volume last written */
326 time_t LabelDate; /* Date/Time Volume labeled */
327 time_t InitialWrite; /* Date/Time Volume first written */
328 int32_t LabelType; /* Label (Bacula/ANSI/IBM) */
329 uint32_t VolJobs; /* number of jobs on this medium */
330 uint32_t VolFiles; /* Number of files */
331 uint32_t VolBlocks; /* Number of blocks */
332 uint32_t VolMounts; /* Number of times mounted */
333 uint32_t VolErrors; /* Number of read/write errors */
334 uint64_t VolWrites; /* Number of writes */
335 uint64_t VolReads; /* Number of reads */
336 uint64_t VolBytes; /* Number of bytes written */
337 uint64_t VolABytes; /* Size of aligned volume */
338 uint64_t VolHoleBytes; /* The size of Holes */
339 uint32_t VolHoles; /* Number of holes */
340 uint32_t VolType; /* Device type of where Volume labeled */
341 uint64_t MaxVolBytes; /* Max bytes to write to Volume */
342 uint64_t VolCapacityBytes; /* capacity estimate */
343 uint64_t VolReadTime; /* time spent reading volume */
344 uint64_t VolWriteTime; /* time spent writing volume */
345 utime_t VolRetention; /* Volume retention in seconds */
346 utime_t VolUseDuration; /* time in secs volume can be used */
347 uint32_t ActionOnPurge; /* action on purge, e.g. truncate the disk volume */
348 uint32_t MaxVolJobs; /* Max Jobs on Volume */
349 uint32_t MaxVolFiles; /* Max files on Volume */
350 int32_t Recycle; /* recycle yes/no */
351 int32_t Slot; /* slot in changer */
352 int32_t Enabled; /* 0=disabled, 1=enabled, 2=archived */
353 int32_t InChanger; /* Volume currently in changer */
354 DBId_t StorageId; /* Storage record Id */
355 uint32_t EndFile; /* Last file on volume */
356 uint32_t EndBlock; /* Last block on volume */
357 uint32_t RecycleCount; /* Number of times recycled */
358 char VolStatus[20]; /* Volume status */
359 DBId_t DeviceId; /* Device where Vol last written */
360 DBId_t LocationId; /* Where Volume is -- user defined */
361 DBId_t ScratchPoolId; /* Where to move if scratch */
362 DBId_t RecyclePoolId; /* Where to move when recycled */
363 /* Extra stuff not in DB */
364 faddr_t rec_addr; /* found record address */
365 /* Since the database returns times as strings, this is how we pass
368 char cFirstWritten[MAX_TIME_LENGTH]; /* FirstWritten returned from DB */
369 char cLastWritten[MAX_TIME_LENGTH]; /* LastWritten returned from DB */
370 char cLabelDate[MAX_TIME_LENGTH]; /* LabelData returned from DB */
371 char cInitialWrite[MAX_TIME_LENGTH]; /* InitialWrite returned from DB */
372 char *exclude_list; /* Optionnal exclude list for db_find_next_volume() */
373 bool set_first_written;
377 /* Client record -- same as the database */
379 DBId_t ClientId; /* Unique Client id */
381 utime_t FileRetention;
382 utime_t JobRetention;
383 char Name[MAX_NAME_LENGTH]; /* Client name */
384 char Uname[256]; /* Uname for client */
387 /* Counter record as in database */
389 char Counter[MAX_NAME_LENGTH];
392 int32_t CurrentValue;
393 char WrapCounter[MAX_NAME_LENGTH];
397 /* FileSet record -- same as the database */
399 DBId_t FileSetId; /* Unique FileSet id */
400 char FileSet[MAX_NAME_LENGTH]; /* FileSet name */
401 char MD5[50]; /* MD5 signature of include/exclude */
402 time_t CreateTime; /* date created */
404 * This is where we return CreateTime
406 char cCreateTime[MAX_TIME_LENGTH]; /* CreateTime as returned from DB */
407 /* Not in DB but returned by db_create_fileset() */
408 bool created; /* set when record newly created */
414 memset(this, 0, sizeof(SNAPSHOT_DBR));
419 void debug(int level) {
420 Dmsg8(DT_SNAPSHOT|level,
429 Name, NPRT(Volume), NPRT(Device), SnapshotId,
430 FileSet, CreateDate, Client, Type);
432 char *as_arg(POOLMEM **out) {
443 Mmsg(out, "name=%s volume=%s device=%s tdate=%d type=%s",
444 Name, NPRTB(Volume), NPRTB(Device), CreateTDate, Type);
449 unbash_spaces(Volume);
452 unbash_spaces(Device);
467 errmsg = Volume = Device = NULL;
469 need_to_free = false;
471 bool need_to_free; /* Need to free the internal memory */
472 /* Used when searching snapshots */
473 char created_after[MAX_TIME_LENGTH];
474 char created_before[MAX_TIME_LENGTH];
475 bool expired; /* Look for CreateTDate > (NOW - Retention) */
476 bool sorted_client; /* Results sorted by Client, SnapshotId */
477 int status; /* Status of the snapshot */
479 DBId_t SnapshotId; /* Unique Snapshot ID */
480 DBId_t JobId; /* Related JobId */
481 DBId_t FileSetId; /* FileSetId if any */
482 DBId_t ClientId; /* From which client this snapshot comes */
483 char Name[MAX_NAME_LENGTH]; /* Snapshot Name */
484 char FileSet[MAX_NAME_LENGTH];/* FileSet name if any */
485 char Client[MAX_NAME_LENGTH]; /* Client name */
486 char Type[MAX_NAME_LENGTH]; /* zfs, btrfs, lvm, netapp, */
487 char Comment[MAX_NAME_LENGTH];/* Comment */
488 char CreateDate[MAX_TIME_LENGTH]; /* Create date as string */
489 time_t CreateTDate; /* Create TDate (in sec, since epoch) */
490 char *Volume; /* Volume taken in snapshot */
491 char *Device; /* Device, Pool, Directory, ... */
492 char *errmsg; /* Error associated with a snapshot */
493 utime_t Retention; /* Number of second before pruning the snapshot */
494 uint64_t Size; /* Snapshot Size */
497 /* Call back context for getting a 32/64 bit value from the database */
500 int64_t value; /* value returned */
501 int count; /* number of values seen */
503 db_int64_ctx() : value(0), count(0) {};
506 db_int64_ctx(const db_int64_ctx&); /* prohibit pass by value */
507 db_int64_ctx &operator=(const db_int64_ctx&); /* prohibit class assignment */
510 /* Call back context for getting a list of comma separated strings from the
515 POOLMEM *list; /* list */
516 int count; /* number of values seen */
518 db_list_ctx() { list = get_pool_memory(PM_FNAME); reset(); }
519 ~db_list_ctx() { free_pool_memory(list); list = NULL; }
520 void reset() { *list = 0; count = 0;}
521 void add(const db_list_ctx &str) {
524 pm_strcat(list, ",");
526 pm_strcat(list, str.list);
530 void add(const char *str) {
532 pm_strcat(list, ",");
534 pm_strcat(list, str);
538 db_list_ctx(const db_list_ctx&); /* prohibit pass by value */
539 db_list_ctx &operator=(const db_list_ctx&); /* prohibit class assignment */
542 /* sql_query flags */
543 #define QF_STORE_RESULT 0x01
547 HORZ_LIST, /* list */
548 VERT_LIST, /* llist */
549 ARG_LIST, /* key1=v1 key2=v2 key3=v3 */
557 #include "sql_cmds.h"
560 /* Object used in db_list_xxx function */
563 char line[256]; /* Used to print last dash line */
566 e_list_type type; /* Vertical/Horizontal */
567 DB_LIST_HANDLER *send; /* send data back */
568 bool once; /* Used to print header one time */
569 void *ctx; /* send() user argument */
584 LIST_CTX(JCR *j, BDB *m, DB_LIST_HANDLER *h, void *c, e_list_type t) {
596 /* Functions exported by sql.c for use within the cats directory. */
597 int list_result(void *vctx, int cols, char **row);
598 int list_result(JCR *jcr, BDB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type);
599 int get_sql_record_max(JCR *jcr, BDB *mdb);
600 void list_dashes(BDB *mdb, DB_LIST_HANDLER *send, void *ctx);
602 void print_dashes(BDB *mdb);
603 void print_result(BDB *mdb);
604 int QueryDB(const char *file, int line, JCR *jcr, BDB *db, char *select_cmd);
605 int InsertDB(const char *file, int line, JCR *jcr, BDB *db, char *select_cmd);
606 int DeleteDB(const char *file, int line, JCR *jcr, BDB *db, char *delete_cmd);
607 void split_path_and_file(JCR *jcr, BDB *mdb, const char *fname);
609 #endif /* __CATS_H_ */