2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 Kern Sibbald
5 Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
7 The original author of Bacula is Kern Sibbald, with contributions
8 from many others, a complete list can be found in the file AUTHORS.
10 You may use this file and others of this release according to the
11 license defined in the LICENSE file, which includes the Affero General
12 Public License, v3.0 ("AGPLv3") and some additional permissions and
13 terms pursuant to its AGPLv3 Section 7.
15 This notice must be preserved when any source code is
16 conveyed and/or propagated.
18 Bacula(R) is a registered trademark of Kern Sibbald.
21 * Catalog DB header file
23 * Written by Kern E. Sibbald
25 * Anyone who accesses the database will need to include
33 Here is how database versions work.
35 While I am working on a new release with database changes, the
36 update scripts are in the src/cats directory under the names
37 update_xxx_tables.in. Most of the time, I make database updates
38 in one go and immediately update the version, but not always. If
39 there are going to be several updates as is the case with version
40 1.37, then I will often forgo changing the version until the last
41 update otherwise I will end up with too many versions and a lot
44 When I am pretty sure there will be no more updates, I will
45 change the version from 8 to 9 (in the present case), and when I
46 am 100% sure there will be no more changes, the update script
47 will be copied to the updatedb directory with the correct name
48 (in the present case 8 to 9).
51 /* Current database version number for all drivers */
52 #define BDB_VERSION 15
54 typedef void (DB_LIST_HANDLER)(void *, const char *);
55 typedef int (DB_RESULT_HANDLER)(void *, int, char **);
57 /* What kind of database we have */
60 SQL_TYPE_POSTGRESQL = 1,
65 /* What kind of driver we have */
67 SQL_DRIVER_TYPE_MYSQL = 0,
68 SQL_DRIVER_TYPE_POSTGRESQL = 1,
69 SQL_DRIVER_TYPE_SQLITE3 = 2,
73 /* ==============================================================
75 * What follows are definitions that are used "globally" for all
76 * the different SQL engines and both inside and external to the
83 * Generic definition of a sql_row.
85 typedef char **SQL_ROW;
88 * Generic definition of a a sql_field.
90 typedef struct sql_field {
91 char *name; /* name of column */
92 int max_length; /* max length */
93 uint32_t type; /* type */
94 uint32_t flags; /* flags */
99 * Structure used when calling db_get_query_ids()
100 * allows the subroutine to return a list of ids.
102 class dbid_list : public SMARTALLOC {
104 DBId_t *DBId; /* array of DBIds */
105 char *PurgedFiles; /* Array of PurgedFile flags */
106 int num_ids; /* num of ids actually stored */
107 int max_ids; /* size of id array */
108 int num_seen; /* number of ids processed */
109 int tot_ids; /* total to process */
111 dbid_list(); /* in sql.c */
112 ~dbid_list(); /* in sql.c */
115 /* Job information passed to create job record and update
116 * job record at end of job. Note, although this record
117 * contains all the fields found in the Job database record,
118 * it also contains fields found in the JobMedia record.
123 char Job[MAX_NAME_LENGTH]; /* Job unique name */
124 char Name[MAX_NAME_LENGTH]; /* Job base name */
125 int JobType; /* actually char(1) */
126 int JobLevel; /* actually char(1) */
127 int JobStatus; /* actually char(1) */
128 DBId_t ClientId; /* Id of client */
129 DBId_t PoolId; /* Id of pool */
130 DBId_t FileSetId; /* Id of FileSet */
131 DBId_t PriorJobId; /* Id of migrated (prior) job */
132 time_t SchedTime; /* Time job scheduled */
133 time_t StartTime; /* Job start time */
134 time_t EndTime; /* Job termination time of orig job */
135 time_t RealEndTime; /* Job termination time of this job */
136 utime_t JobTDate; /* Backup time/date in seconds */
137 uint32_t VolSessionId;
138 uint32_t VolSessionTime;
141 uint32_t JobMissingFiles;
147 /* Note, FirstIndex, LastIndex, Start/End File and Block
148 * are only used in the JobMedia record.
150 uint32_t FirstIndex; /* First index this Volume */
151 uint32_t LastIndex; /* Last index this Volume */
157 char cSchedTime[MAX_TIME_LENGTH];
158 char cStartTime[MAX_TIME_LENGTH];
159 char cEndTime[MAX_TIME_LENGTH];
160 char cRealEndTime[MAX_TIME_LENGTH];
161 /* Extra stuff not in DB */
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 bool set_first_written;
376 /* Client record -- same as the database */
378 DBId_t ClientId; /* Unique Client id */
380 utime_t FileRetention;
381 utime_t JobRetention;
382 char Name[MAX_NAME_LENGTH]; /* Client name */
383 char Uname[256]; /* Uname for client */
386 /* Counter record as in database */
388 char Counter[MAX_NAME_LENGTH];
391 int32_t CurrentValue;
392 char WrapCounter[MAX_NAME_LENGTH];
396 /* FileSet record -- same as the database */
398 DBId_t FileSetId; /* Unique FileSet id */
399 char FileSet[MAX_NAME_LENGTH]; /* FileSet name */
400 char MD5[50]; /* MD5 signature of include/exclude */
401 time_t CreateTime; /* date created */
403 * This is where we return CreateTime
405 char cCreateTime[MAX_TIME_LENGTH]; /* CreateTime as returned from DB */
406 /* Not in DB but returned by db_create_fileset() */
407 bool created; /* set when record newly created */
413 memset(this, 0, sizeof(SNAPSHOT_DBR));
418 void debug(int level) {
419 Dmsg8(DT_SNAPSHOT|level,
428 Name, NPRT(Volume), NPRT(Device), SnapshotId,
429 FileSet, CreateDate, Client, Type);
431 char *as_arg(POOLMEM **out) {
442 Mmsg(out, "name=%s volume=%s device=%s tdate=%d type=%s",
443 Name, NPRTB(Volume), NPRTB(Device), CreateTDate, Type);
448 unbash_spaces(Volume);
451 unbash_spaces(Device);
466 errmsg = Volume = Device = NULL;
468 need_to_free = false;
470 bool need_to_free; /* Need to free the internal memory */
471 /* Used when searching snapshots */
472 char created_after[MAX_TIME_LENGTH];
473 char created_before[MAX_TIME_LENGTH];
474 bool expired; /* Look for CreateTDate > (NOW - Retention) */
475 bool sorted_client; /* Results sorted by Client, SnapshotId */
476 int status; /* Status of the snapshot */
478 DBId_t SnapshotId; /* Unique Snapshot ID */
479 DBId_t JobId; /* Related JobId */
480 DBId_t FileSetId; /* FileSetId if any */
481 DBId_t ClientId; /* From which client this snapshot comes */
482 char Name[MAX_NAME_LENGTH]; /* Snapshot Name */
483 char FileSet[MAX_NAME_LENGTH];/* FileSet name if any */
484 char Client[MAX_NAME_LENGTH]; /* Client name */
485 char Type[MAX_NAME_LENGTH]; /* zfs, btrfs, lvm, netapp, */
486 char Comment[MAX_NAME_LENGTH];/* Comment */
487 char CreateDate[MAX_TIME_LENGTH]; /* Create date as string */
488 time_t CreateTDate; /* Create TDate (in sec, since epoch) */
489 char *Volume; /* Volume taken in snapshot */
490 char *Device; /* Device, Pool, Directory, ... */
491 char *errmsg; /* Error associated with a snapshot */
492 utime_t Retention; /* Number of second before pruning the snapshot */
493 uint64_t Size; /* Snapshot Size */
496 /* Call back context for getting a 32/64 bit value from the database */
499 int64_t value; /* value returned */
500 int count; /* number of values seen */
502 db_int64_ctx() : value(0), count(0) {};
505 db_int64_ctx(const db_int64_ctx&); /* prohibit pass by value */
506 db_int64_ctx &operator=(const db_int64_ctx&); /* prohibit class assignment */
509 /* Call back context for getting a list of comma separated strings from the
514 POOLMEM *list; /* list */
515 int count; /* number of values seen */
517 db_list_ctx() { list = get_pool_memory(PM_FNAME); reset(); }
518 ~db_list_ctx() { free_pool_memory(list); list = NULL; }
519 void reset() { *list = 0; count = 0;}
520 void add(const db_list_ctx &str) {
523 pm_strcat(list, ",");
525 pm_strcat(list, str.list);
529 void add(const char *str) {
531 pm_strcat(list, ",");
533 pm_strcat(list, str);
537 db_list_ctx(const db_list_ctx&); /* prohibit pass by value */
538 db_list_ctx &operator=(const db_list_ctx&); /* prohibit class assignment */
541 /* sql_query flags */
542 #define QF_STORE_RESULT 0x01
546 HORZ_LIST, /* list */
547 VERT_LIST, /* llist */
548 ARG_LIST, /* key1=v1 key2=v2 key3=v3 */
556 #include "sql_cmds.h"
559 /* Object used in db_list_xxx function */
562 char line[256]; /* Used to print last dash line */
565 e_list_type type; /* Vertical/Horizontal */
566 DB_LIST_HANDLER *send; /* send data back */
567 bool once; /* Used to print header one time */
568 void *ctx; /* send() user argument */
583 LIST_CTX(JCR *j, BDB *m, DB_LIST_HANDLER *h, void *c, e_list_type t) {
595 /* Functions exported by sql.c for use within the cats directory. */
596 int list_result(void *vctx, int cols, char **row);
597 int list_result(JCR *jcr, BDB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type);
598 int get_sql_record_max(JCR *jcr, BDB *mdb);
599 void list_dashes(BDB *mdb, DB_LIST_HANDLER *send, void *ctx);
601 void print_dashes(BDB *mdb);
602 void print_result(BDB *mdb);
603 int QueryDB(const char *file, int line, JCR *jcr, BDB *db, char *select_cmd);
604 int InsertDB(const char *file, int line, JCR *jcr, BDB *db, char *select_cmd);
605 int DeleteDB(const char *file, int line, JCR *jcr, BDB *db, char *delete_cmd);
606 void split_path_and_file(JCR *jcr, BDB *mdb, const char *fname);
608 #endif /* __CATS_H_ */