]> git.sur5r.net Git - bacula/docs/blob - docs/manuals/en/developers/catalog.tex
Developers, misc and problems manuals
[bacula/docs] / docs / manuals / en / developers / catalog.tex
1 %%
2 %%
3
4 \chapter{Catalog Services}
5 \label{_ChapterStart30}
6 \index[general]{Services!Catalog }
7 \index[general]{Catalog Services }
8
9 \section{General}
10 \index[general]{General }
11 \addcontentsline{toc}{subsection}{General}
12
13 This chapter is intended to be a technical discussion of the Catalog services
14 and as such is not targeted at end users but rather at developers and system
15 administrators that want or need to know more of the working details of {\bf
16 Bacula}.
17
18 The {\bf Bacula Catalog} services consist of the programs that provide the SQL
19 database engine for storage and retrieval of all information concerning files
20 that were backed up and their locations on the storage media.
21
22 We have investigated the possibility of using the following SQL engines for
23 Bacula: Beagle, mSQL, GNU SQL, PostgreSQL, SQLite, Oracle, and MySQL. Each
24 presents certain problems with either licensing or maturity. At present, we
25 have chosen for development purposes to use MySQL, PostgreSQL and SQLite.
26 MySQL was chosen because it is fast, proven to be reliable, widely used, and
27 actively being developed. MySQL is released under the GNU GPL license.
28 PostgreSQL was chosen because it is a full-featured, very mature database, and
29 because Dan Langille did the Bacula driver for it. PostgreSQL is distributed
30 under the BSD license. SQLite was chosen because it is small, efficient, and
31 can be directly embedded in {\bf Bacula} thus requiring much less effort from
32 the system administrator or person building {\bf Bacula}. In our testing
33 SQLite has performed very well, and for the functions that we use, it has
34 never encountered any errors except that it does not appear to handle
35 databases larger than 2GBytes. That said, we would not recommend it for
36 serious production use.
37
38 The Bacula SQL code has been written in a manner that will allow it to be
39 easily modified to support any of the current SQL database systems on the
40 market (for example: mSQL, iODBC, unixODBC, Solid, OpenLink ODBC, EasySoft
41 ODBC, InterBase, Oracle8, Oracle7, and DB2).
42
43 If you do not specify either \lstinline+--with-mysql+ or \lstinline+--with-postgresq+ or
44 \lstinline+--with-sqlite+ on the ./configure line, Bacula will use its minimalist
45 internal database. This database is kept for build reasons but is no longer
46 supported. Bacula {\bf requires} one of the three databases (MySQL,
47 PostgreSQL, or SQLite) to run.
48
49 \subsection{Filenames and Maximum Filename Length}
50 \index[general]{Filenames and Maximum Filename Length }
51 \index[general]{Length!Filenames and Maximum Filename }
52 \addcontentsline{toc}{subsubsection}{Filenames and Maximum Filename Length}
53
54 In general, either MySQL, PostgreSQL or SQLite permit storing arbitrary long
55 path names and file names in the catalog database. In practice, there still
56 may be one or two places in the Catalog interface code that restrict the
57 maximum path length to 512 characters and the maximum file name length to 512
58 characters. These restrictions are believed to have been removed. Please note,
59 these restrictions apply only to the Catalog database and thus to your ability
60 to list online the files saved during any job. All information received and
61 stored by the Storage daemon (normally on tape) allows and handles arbitrarily
62 long path and filenames.
63
64 \subsection{Installing and Configuring MySQL}
65 \index[general]{MySQL!Installing and Configuring }
66 \index[general]{Installing and Configuring MySQL }
67 %\addcontentsline{toc}{subsubsection}{Installing and Configuring MySQL}
68
69 For the details of installing and configuring MySQL, please see the
70 \bsysxrlink{Installing and Configuring MySQL}{MySqlChapter}{main}{chapter} of
71 the \mainman{}.
72
73 \subsection{Installing and Configuring PostgreSQL}
74 \index[general]{PostgreSQL!Installing and Configuring }
75 \index[general]{Installing and Configuring PostgreSQL }
76 %\addcontentsline{toc}{subsubsection}{Installing and Configuring PostgreSQL}
77
78 For the details of installing and configuring PostgreSQL, please see the
79 \bsysxrlink{Installing and Configuring PostgreSQL}{PostgreSqlChapter}{main}{chapter}
80  of the \mainman{}.
81
82 \subsection{Installing and Configuring SQLite}
83 \index[general]{Installing and Configuring SQLite }
84 \index[general]{SQLite!Installing and Configuring }
85 %\addcontentsline{toc}{subsubsection}{Installing and Configuring SQLite}
86
87 For the details of installing and configuring SQLite, please see the
88 \bsysxrlink{Installing and Configuring SQLite}{SqlLiteChapter}{main}{chapter} of
89 the \mainman{}.
90
91 \subsection{Internal Bacula Catalog}
92 \index[general]{Catalog!Internal Bacula }
93 \index[general]{Internal Bacula Catalog }
94 %\addcontentsline{toc}{subsubsection}{Internal Bacula Catalog}
95
96 Please see the \bsysxrlink{Internal Bacula Database}
97 {chap:InternalBaculaDatabase}{misc}{chapter} of the \miscman{} for more details.
98
99 \subsection{Database Table Design}
100 \index[general]{Design!Database Table }
101 \index[general]{Database Table Design }
102 %\addcontentsline{toc}{subsubsection}{Database Table Design}
103
104 All discussions that follow pertain to the MySQL database. The details for the
105 PostgreSQL and SQLite databases are essentially identical except for that all
106 fields in the SQLite database are stored as ASCII text and some of the
107 database creation statements are a bit different. The details of the internal
108 Bacula catalog are not discussed here.
109
110 Because the Catalog database may contain very large amounts of data for large
111 sites, we have made a modest attempt to normalize the data tables to reduce
112 redundant information. While reducing the size of the database significantly,
113 it does, unfortunately, add some complications to the structures.
114
115 In simple terms, the Catalog database must contain a record of all Jobs run by
116 Bacula, and for each Job, it must maintain a list of all files saved, with
117 their File Attributes (permissions, create date, ...), and the location and
118 Media on which the file is stored. This is seemingly a simple task, but it
119 represents a huge amount interlinked data. Note: the list of files and their
120 attributes is not maintained when using the internal Bacula database. The data
121 stored in the File records, which allows the user or administrator to obtain a
122 list of all files backed up during a job, is by far the largest volume of
123 information put into the Catalog database.
124
125 Although the Catalog database has been designed to handle backup data for
126 multiple clients, some users may want to maintain multiple databases, one for
127 each machine to be backed up. This reduces the risk of confusion of accidental
128 restoring a file to the wrong machine as well as reducing the amount of data
129 in a single database, thus increasing efficiency and reducing the impact of a
130 lost or damaged database.
131
132 \section{Sequence of Creation of Records for a Save Job}
133 \index[general]{Sequence of Creation of Records for a Save Job }
134 \index[general]{Job!Sequence of Creation of Records for a Save }
135 \addcontentsline{toc}{subsection}{Sequence of Creation of Records for a Save
136 Job}
137
138 Start with StartDate, ClientName, Filename, Path, Attributes, MediaName,
139 MediaCoordinates. (PartNumber, NumParts). In the steps below, ``Create new''
140 means to create a new record whether or not it is unique. ``Create unique''
141 means each record in the database should be unique. Thus, one must first
142 search to see if the record exists, and only if not should a new one be
143 created, otherwise the existing RecordId should be used.
144
145 \begin{enumerate}
146 \item Create new Job record with StartDate; save JobId
147 \item Create unique Media record; save MediaId
148 \item Create unique Client record; save ClientId
149 \item Create unique Filename record; save FilenameId
150 \item Create unique Path record; save PathId
151 \item Create unique Attribute record; save AttributeId
152    store ClientId, FilenameId, PathId, and Attributes
153 \item Create new File record
154    store JobId, AttributeId, MediaCoordinates, etc
155 \item Repeat steps 4 through 8 for each file
156 \item Create a JobMedia record; save MediaId
157 \item Update Job record filling in EndDate and other Job statistics
158    \end{enumerate}
159
160 \section{Database Tables}
161 \index[general]{Database Tables }
162 \index[general]{Tables!Database }
163 %\addcontentsline{toc}{subsection}{Database Tables}
164 %\addcontentsline{lot}{table}{Filename Table Layout}
165 \LTXtable{\linewidth}{table_dbfilename}
166
167 The {\bf Filename} table \bsysref{table:dbfilename} contains the name of each file backed up
168 with the path removed. If different directories or machines contain the same
169 filename, only one copy will be saved in this table.
170
171 %\addcontentsline{lot}{table}{Path Table Layout}
172 \LTXtable{\linewidth}{table_dbpath}
173
174 The {\bf Path} table \bsysref{table:dbpath} contains the path or directory names of all
175 directories on the system or systems. The filename and any MSDOS disk name are
176 stripped off. As with the filename, only one copy of each directory name is
177 kept regardless of how many machines or drives have the same directory. These
178 path names should be stored in Unix path name format.
179
180 Some simple testing on a Linux file system indicates that separating the
181 filename and the path may be more complication than is warranted by the space
182 savings. For example, this system has a total of 89,097 files, 60,467 of which
183 have unique filenames, and there are 4,374 unique paths.
184
185 Finding all those files and doing two stats() per file takes an average wall
186 clock time of 1 min 35 seconds on a 400MHz machine running RedHat 6.1 Linux.
187
188 Finding all those files and putting them directly into a MySQL database with
189 the path and filename defined as TEXT, which is variable length up to 65,535
190 characters takes 19 mins 31 seconds and creates a 27.6 MByte database.
191
192 Doing the same thing, but inserting them into Blob fields with the filename
193 indexed on the first 30 characters and the path name indexed on the 255 (max)
194 characters takes 5 mins 18 seconds and creates a 5.24 MB database. Rerunning
195 the job (with the database already created) takes about 2 mins 50 seconds.
196
197 Running the same as the last one (Path and Filename Blob), but Filename
198 indexed on the first 30 characters and the Path on the first 50 characters
199 (linear search done there after) takes 5 mins on the average and creates a 3.4
200 MB database. Rerunning with the data already in the DB takes 3 mins 35
201 seconds.
202
203 Finally, saving only the full path name rather than splitting the path and the
204 file, and indexing it on the first 50 characters takes 6 mins 43 seconds and
205 creates a 7.35 MB database.
206
207
208 %\addcontentsline{lot}{table}
209 \LTXtable{\linewidth}{table_dbfile}
210
211 The {\bf File} table \bsysref{table:dbfile} contains one entry for each file backed up by
212 Bacula. Thus a file that is backed up multiple times (as is normal) will have
213 multiple entries in the File table. This will probably be the table with the
214 most number of records. Consequently, it is essential to keep the size of this
215 record to an absolute minimum. At the same time, this table must contain all
216 the information (or pointers to the information) about the file and where it
217 is backed up. Since a file may be backed up many times without having changed,
218 the path and filename are stored in separate tables.
219
220 This table contains by far the largest amount of information in the Catalog
221 database, both from the stand point of number of records, and the stand point
222 of total database size. As a consequence, the user must take care to
223 periodically reduce the number of File records using the {\bf retention}
224 command in the Console program.
225
226 %\addcontentsline{lot}{table}{Job Table Layout}
227 \LTXtable{\linewidth}{table_dbjob}
228
229 The {\bf Job} table \bsysref{table:dbjob} contains one record for each Job run by Bacula. Thus
230 normally, there will be one per day per machine added to the database. Note,
231 the JobId is used to index Job records in the database, and it often is shown
232 to the user in the Console program. However, care must be taken with its use
233 as it is not unique from database to database. For example, the user may have
234 a database for Client data saved on machine Rufus and another database for
235 Client data saved on machine Roxie. In this case, the two database will each
236 have JobIds that match those in another database. For a unique reference to a
237 Job, see Job below.
238
239 The Name field of the Job record corresponds to the Name resource record given
240 in the Director's configuration file. Thus it is a generic name, and it will
241 be normal to find many Jobs (or even all Jobs) with the same Name.
242
243 The Job field contains a combination of the Name and the schedule time of the
244 Job by the Director. Thus for a given Director, even with multiple Catalog
245 databases, the Job will contain a unique name that represents the Job.
246
247 For a given Storage daemon, the VolSessionId and VolSessionTime form a unique
248 identification of the Job. This will be the case even if multiple Directors
249 are using the same Storage daemon.
250
251 The Job Type (or simply Type) can have one of the following values:
252
253 %\addcontentsline{lot}{table}{Job Types}
254 \LTXtable{\linewidth}{table_dbjobtypes}
255 Note, the Job Type values in table \bsysref{table:dbjobtypes} noted above are not kept in an SQL table.
256
257
258 The JobStatus field specifies how the job terminated, and can be one of the
259 following:
260 \LTXtable{\linewidth}{table_dbjobstatuses}
261
262
263 %\addcontentsline{lot}{table}{File Sets Table Layout}
264 \LTXtable{\linewidth}{table_dbfileset}
265
266 The {\bf FileSet} table \bsysref{table:dbfileset} contains one entry for each FileSet that is used. The
267 MD5 signature is kept to ensure that if the user changes anything inside the
268 FileSet, it will be detected and the new FileSet will be used. This is
269 particularly important when doing an incremental update. If the user deletes a
270 file or adds a file, we need to ensure that a Full backup is done prior to the
271 next incremental.
272
273
274 %\addcontentsline{lot}{table}
275 \LTXtable{\linewidth}{table_dbjobmedia}
276
277 The {\bf JobMedia} table \bsysref{table:dbjobmedia} contains one entry at the following: start of
278 the job, start of each new tape file, start of each new tape, end of the
279 job.  Since by default, a new tape file is written every 2GB, in general,
280 you will have more than 2 JobMedia records per Job.  The number can be
281 varied by changing the "Maximum File Size" specified in the Device
282 resource.  This record allows Bacula to efficiently position close to
283 (within 2GB) any given file in a backup.  For restoring a full Job,
284 these records are not very important, but if you want to retrieve
285 a single file that was written near the end of a 100GB backup, the
286 JobMedia records can speed it up by orders of magnitude by permitting
287 forward spacing files and blocks rather than reading the whole 100GB
288 backup.
289
290
291
292
293 %\addcontentsline{lot}{table}{Media Table Layout}
294 \LTXtable{\linewidth}{table_dbmedia}
295
296 The {\bf Volume} table\footnote{Internally referred to as the Media table} \bsysref{table:dbmedia}  contains
297 one entry for each volume, that is each tape, cassette (8mm, DLT, DAT, ...),
298 or file on which information is or was backed up. There is one Volume record
299 created for each of the NumVols specified in the Pool resource record.
300
301 %\addcontentsline{lot}{table}{Pool Table Layout}
302 \LTXtable{\linewidth}{table_dbpool}
303
304 The {\bf Pool} table \bsysref{table:dbpool} contains one entry for each media pool controlled by
305 Bacula in this database. One media record exists for each of the NumVols
306 contained in the Pool. The PoolType is a Bacula defined keyword. The MediaType
307 is defined by the administrator, and corresponds to the MediaType specified in
308 the Director's Storage definition record. The CurrentVol is the sequence
309 number of the Media record for the current volume.
310
311
312 %\addcontentsline{lot}{table}{Client Table Layout}
313 \LTXtable{\linewidth}{table_dbclient}
314
315 The {\bf Client} table \bsysref{table:dbclient} contains one entry for each machine backed up by Bacula
316 in this database. Normally the Name is a fully qualified domain name.
317
318
319 %\addcontentsline{lot}{table}{Storage Table Layout}
320 \LTXtable{\linewidth}{table_dbstorage}
321
322 The {\bf Storage} table \bsysref{table:dbstorage} contains one entry for each Storage used.
323
324
325 %\addcontentsline{lot}{table}{Counter Table Layout}
326 \LTXtable{\linewidth}{table_dbcounter}
327
328 The {\bf Counter} table \bsysref{table:dbcounter} contains one entry for each permanent counter defined
329 by the user.
330
331 %\addcontentsline{lot}{table}{Job History Table Layout}
332 \LTXtable{\linewidth}{table_dbjobhistory}
333
334 The {\bf JobHisto} table \bsysref{table:dbjobhistory} is the same as the Job table, but it keeps
335 long term statistics (i.e. it is not pruned with the Job).
336
337
338 %\addcontentsline{lot}{table}{Log Table Layout}
339 \LTXtable{\linewidth}{table_dblog}
340
341 The {\bf Log} table \bsysref{table:dblog} contains a log of all Job output.
342
343 %\addcontentsline{lot}{table}{Location Table Layout}
344 \LTXtable{\linewidth}{table_dblocation}
345
346 The {\bf Location} table \bsysref{table:dblocation} defines where a Volume is physically.
347
348
349 %\addcontentsline{lot}{table}{Location Log Table Layout}
350 \LTXtable{\linewidth}{table_dblocationlog}
351
352 The {\bf Location Log} table \bsysref{table:dblocationlog} contains a log of all Job output.
353
354
355 %\addcontentsline{lot}{table}{Version Table Layout}
356 \LTXtable{\linewidth}{table_dbversion}
357
358 The {\bf Version} table \bsysref{table:dbversion} defines the Bacula database version number. Bacula
359 checks this number before reading the database to ensure that it is compatible
360 with the Bacula binary file.
361
362
363 %\addcontentsline{lot}{table}{Base Files Table Layout}
364 \LTXtable{\linewidth}{table_dbbasefiles}
365
366 The {\bf BaseFiles} table \bsysref{table:dbbasefiles} contains all the File references for a particular
367 JobId that point to a Base file -- i.e. they were previously saved and hence
368 were not saved in the current JobId but in BaseJobId under FileId. FileIndex
369 is the index of the file, and is used for optimization of Restore jobs to
370 prevent the need to read the FileId record when creating the in memory tree.
371 This record is not yet implemented.
372
373 \
374
375 \subsection{MySQL Table Definition}
376 \index[general]{MySQL Table Definition }
377 \index[general]{Definition!MySQL Table }
378 \addcontentsline{toc}{subsubsection}{MySQL Table Definition}
379
380 The commands used to create the MySQL tables are as follows:
381
382 \footnotesize
383 \begin{lstlisting}
384 USE bacula;
385 CREATE TABLE Filename (
386   FilenameId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
387   Name BLOB NOT NULL,
388   PRIMARY KEY(FilenameId),
389   INDEX (Name(30))
390   );
391 CREATE TABLE Path (
392    PathId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
393    Path BLOB NOT NULL,
394    PRIMARY KEY(PathId),
395    INDEX (Path(50))
396    );
397 CREATE TABLE File (
398    FileId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
399    FileIndex INTEGER UNSIGNED NOT NULL DEFAULT 0,
400    JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
401    PathId INTEGER UNSIGNED NOT NULL REFERENCES Path,
402    FilenameId INTEGER UNSIGNED NOT NULL REFERENCES Filename,
403    MarkId INTEGER UNSIGNED NOT NULL DEFAULT 0,
404    LStat TINYBLOB NOT NULL,
405    MD5 TINYBLOB NOT NULL,
406    PRIMARY KEY(FileId),
407    INDEX (JobId),
408    INDEX (PathId),
409    INDEX (FilenameId)
410    );
411 CREATE TABLE Job (
412    JobId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
413    Job TINYBLOB NOT NULL,
414    Name TINYBLOB NOT NULL,
415    Type BINARY(1) NOT NULL,
416    Level BINARY(1) NOT NULL,
417    ClientId INTEGER NOT NULL REFERENCES Client,
418    JobStatus BINARY(1) NOT NULL,
419    SchedTime DATETIME NOT NULL,
420    StartTime DATETIME NOT NULL,
421    EndTime DATETIME NOT NULL,
422    JobTDate BIGINT UNSIGNED NOT NULL,
423    VolSessionId INTEGER UNSIGNED NOT NULL DEFAULT 0,
424    VolSessionTime INTEGER UNSIGNED NOT NULL DEFAULT 0,
425    JobFiles INTEGER UNSIGNED NOT NULL DEFAULT 0,
426    JobBytes BIGINT UNSIGNED NOT NULL,
427    JobErrors INTEGER UNSIGNED NOT NULL DEFAULT 0,
428    JobMissingFiles INTEGER UNSIGNED NOT NULL DEFAULT 0,
429    PoolId INTEGER UNSIGNED NOT NULL REFERENCES Pool,
430    FileSetId INTEGER UNSIGNED NOT NULL REFERENCES FileSet,
431    PurgedFiles TINYINT NOT NULL DEFAULT 0,
432    HasBase TINYINT NOT NULL DEFAULT 0,
433    PRIMARY KEY(JobId),
434    INDEX (Name(128))
435    );
436 CREATE TABLE FileSet (
437    FileSetId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
438    FileSet TINYBLOB NOT NULL,
439    MD5 TINYBLOB NOT NULL,
440    CreateTime DATETIME NOT NULL,
441    PRIMARY KEY(FileSetId)
442    );
443 CREATE TABLE JobMedia (
444    JobMediaId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
445    JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
446    MediaId INTEGER UNSIGNED NOT NULL REFERENCES Media,
447    FirstIndex INTEGER UNSIGNED NOT NULL DEFAULT 0,
448    LastIndex INTEGER UNSIGNED NOT NULL DEFAULT 0,
449    StartFile INTEGER UNSIGNED NOT NULL DEFAULT 0,
450    EndFile INTEGER UNSIGNED NOT NULL DEFAULT 0,
451    StartBlock INTEGER UNSIGNED NOT NULL DEFAULT 0,
452    EndBlock INTEGER UNSIGNED NOT NULL DEFAULT 0,
453    VolIndex INTEGER UNSIGNED NOT NULL DEFAULT 0,
454    PRIMARY KEY(JobMediaId),
455    INDEX (JobId, MediaId)
456    );
457 CREATE TABLE Media (
458    MediaId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
459    VolumeName TINYBLOB NOT NULL,
460    Slot INTEGER NOT NULL DEFAULT 0,
461    PoolId INTEGER UNSIGNED NOT NULL REFERENCES Pool,
462    MediaType TINYBLOB NOT NULL,
463    FirstWritten DATETIME NOT NULL,
464    LastWritten DATETIME NOT NULL,
465    LabelDate DATETIME NOT NULL,
466    VolJobs INTEGER UNSIGNED NOT NULL DEFAULT 0,
467    VolFiles INTEGER UNSIGNED NOT NULL DEFAULT 0,
468    VolBlocks INTEGER UNSIGNED NOT NULL DEFAULT 0,
469    VolMounts INTEGER UNSIGNED NOT NULL DEFAULT 0,
470    VolBytes BIGINT UNSIGNED NOT NULL DEFAULT 0,
471    VolErrors INTEGER UNSIGNED NOT NULL DEFAULT 0,
472    VolWrites INTEGER UNSIGNED NOT NULL DEFAULT 0,
473    VolCapacityBytes BIGINT UNSIGNED NOT NULL,
474    VolStatus ENUM('Full', 'Archive', 'Append', 'Recycle', 'Purged',
475     'Read-Only', 'Disabled', 'Error', 'Busy', 'Used', 'Cleaning') NOT NULL,
476    Recycle TINYINT NOT NULL DEFAULT 0,
477    VolRetention BIGINT UNSIGNED NOT NULL DEFAULT 0,
478    VolUseDuration BIGINT UNSIGNED NOT NULL DEFAULT 0,
479    MaxVolJobs INTEGER UNSIGNED NOT NULL DEFAULT 0,
480    MaxVolFiles INTEGER UNSIGNED NOT NULL DEFAULT 0,
481    MaxVolBytes BIGINT UNSIGNED NOT NULL DEFAULT 0,
482    InChanger TINYINT NOT NULL DEFAULT 0,
483    MediaAddressing TINYINT NOT NULL DEFAULT 0,
484    VolReadTime BIGINT UNSIGNED NOT NULL DEFAULT 0,
485    VolWriteTime BIGINT UNSIGNED NOT NULL DEFAULT 0,
486    PRIMARY KEY(MediaId),
487    INDEX (PoolId)
488    );
489 CREATE TABLE Pool (
490    PoolId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
491    Name TINYBLOB NOT NULL,
492    NumVols INTEGER UNSIGNED NOT NULL DEFAULT 0,
493    MaxVols INTEGER UNSIGNED NOT NULL DEFAULT 0,
494    UseOnce TINYINT NOT NULL,
495    UseCatalog TINYINT NOT NULL,
496    AcceptAnyVolume TINYINT DEFAULT 0,
497    VolRetention BIGINT UNSIGNED NOT NULL,
498    VolUseDuration BIGINT UNSIGNED NOT NULL,
499    MaxVolJobs INTEGER UNSIGNED NOT NULL DEFAULT 0,
500    MaxVolFiles INTEGER UNSIGNED NOT NULL DEFAULT 0,
501    MaxVolBytes BIGINT UNSIGNED NOT NULL,
502    AutoPrune TINYINT DEFAULT 0,
503    Recycle TINYINT DEFAULT 0,
504    PoolType ENUM('Backup', 'Copy', 'Cloned', 'Archive', 'Migration', 'Scratch') NOT NULL,
505    LabelFormat TINYBLOB,
506    Enabled TINYINT DEFAULT 1,
507    ScratchPoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool,
508    RecyclePoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool,
509    UNIQUE (Name(128)),
510    PRIMARY KEY (PoolId)
511    );
512 CREATE TABLE Client (
513    ClientId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
514    Name TINYBLOB NOT NULL,
515    Uname TINYBLOB NOT NULL,       /* full uname -a of client */
516    AutoPrune TINYINT DEFAULT 0,
517    FileRetention BIGINT UNSIGNED NOT NULL,
518    JobRetention  BIGINT UNSIGNED NOT NULL,
519    UNIQUE (Name(128)),
520    PRIMARY KEY(ClientId)
521    );
522 CREATE TABLE BaseFiles (
523    BaseId INTEGER UNSIGNED AUTO_INCREMENT,
524    BaseJobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
525    JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
526    FileId INTEGER UNSIGNED NOT NULL REFERENCES File,
527    FileIndex INTEGER UNSIGNED,
528    PRIMARY KEY(BaseId)
529    );
530 CREATE TABLE UnsavedFiles (
531    UnsavedId INTEGER UNSIGNED AUTO_INCREMENT,
532    JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
533    PathId INTEGER UNSIGNED NOT NULL REFERENCES Path,
534    FilenameId INTEGER UNSIGNED NOT NULL REFERENCES Filename,
535    PRIMARY KEY (UnsavedId)
536    );
537 CREATE TABLE Version (
538    VersionId INTEGER UNSIGNED NOT NULL
539    );
540 -- Initialize Version
541 INSERT INTO Version (VersionId) VALUES (7);
542 CREATE TABLE Counters (
543    Counter TINYBLOB NOT NULL,
544    MinValue INTEGER,
545    MaxValue INTEGER,
546    CurrentValue INTEGER,
547    WrapCounter TINYBLOB NOT NULL,
548    PRIMARY KEY (Counter(128))
549    );
550 \end{lstlisting}
551 \normalsize