~ubuntu-branches/ubuntu/gutsy/bacula-doc/gutsy

« back to all changes in this revision

Viewing changes to developers/catalog.tex

  • Committer: Bazaar Package Importer
  • Author(s): John Goerzen
  • Date: 2006-08-15 09:44:08 UTC
  • Revision ID: james.westby@ubuntu.com-20060815094408-1kvvfls2hs3d9uw8
Tags: upstream-1.38.11.1
ImportĀ upstreamĀ versionĀ 1.38.11.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
%%
 
2
%%
 
3
 
 
4
\section*{Catalog Services}
 
5
\label{_ChapterStart30}
 
6
\index[general]{Services!Catalog }
 
7
\index[general]{Catalog Services }
 
8
\addcontentsline{toc}{section}{Catalog Services}
 
9
 
 
10
\subsection*{General}
 
11
\index[general]{General }
 
12
\addcontentsline{toc}{subsection}{General}
 
13
 
 
14
This chapter is intended to be a technical discussion of the Catalog services
 
15
and as such is not targeted at end users but rather at developers and system
 
16
administrators that want or need to know more of the working details of {\bf
 
17
Bacula}. 
 
18
 
 
19
The {\bf Bacula Catalog} services consist of the programs that provide the SQL
 
20
database engine for storage and retrieval of all information concerning files
 
21
that were backed up and their locations on the storage media. 
 
22
 
 
23
We have investigated the possibility of using the following SQL engines for
 
24
Bacula: Beagle, mSQL, GNU SQL, PostgreSQL, SQLite, Oracle, and MySQL. Each
 
25
presents certain problems with either licensing or maturity. At present, we
 
26
have chosen for development purposes to use MySQL, PostgreSQL and SQLite.
 
27
MySQL was chosen because it is fast, proven to be reliable, widely used, and
 
28
actively being developed. MySQL is released under the GNU GPL license.
 
29
PostgreSQL was chosen because it is a full-featured, very mature database, and
 
30
because Dan Langille did the Bacula driver for it. PostgreSQL is distributed
 
31
under the BSD license. SQLite was chosen because it is small, efficient, and
 
32
can be directly embedded in {\bf Bacula} thus requiring much less effort from
 
33
the system administrator or person building {\bf Bacula}. In our testing
 
34
SQLite has performed very well, and for the functions that we use, it has
 
35
never encountered any errors except that it does not appear to handle
 
36
databases larger than 2GBytes. That said, we would not recommend it for
 
37
serious production use.
 
38
 
 
39
The Bacula SQL code has been written in a manner that will allow it to be
 
40
easily modified to support any of the current SQL database systems on the
 
41
market (for example: mSQL, iODBC, unixODBC, Solid, OpenLink ODBC, EasySoft
 
42
ODBC, InterBase, Oracle8, Oracle7, and DB2). 
 
43
 
 
44
If you do not specify either {\bf \verb{--{with-mysql} or {\bf \verb{--{with-postgresql} or
 
45
{\bf \verb{--{with-sqlite} on the ./configure line, Bacula will use its minimalist
 
46
internal database. This database is kept for build reasons but is no longer
 
47
supported. Bacula {\bf requires} one of the three databases (MySQL,
 
48
PostgreSQL, or SQLite) to run. 
 
49
 
 
50
\subsubsection*{Filenames and Maximum Filename Length}
 
51
\index[general]{Filenames and Maximum Filename Length }
 
52
\index[general]{Length!Filenames and Maximum Filename }
 
53
\addcontentsline{toc}{subsubsection}{Filenames and Maximum Filename Length}
 
54
 
 
55
In general, either MySQL, PostgreSQL or SQLite permit storing arbitrary long
 
56
path names and file names in the catalog database. In practice, there still
 
57
may be one or two places in the Catalog interface code that restrict the
 
58
maximum path length to 512 characters and the maximum file name length to 512
 
59
characters. These restrictions are believed to have been removed. Please note,
 
60
these restrictions apply only to the Catalog database and thus to your ability
 
61
to list online the files saved during any job. All information received and
 
62
stored by the Storage daemon (normally on tape) allows and handles arbitrarily
 
63
long path and filenames. 
 
64
 
 
65
\subsubsection*{Installing and Configuring MySQL}
 
66
\index[general]{MySQL!Installing and Configuring }
 
67
\index[general]{Installing and Configuring MySQL }
 
68
\addcontentsline{toc}{subsubsection}{Installing and Configuring MySQL}
 
69
 
 
70
For the details of installing and configuring MySQL, please see the 
 
71
\ilink{Installing and Configuring MySQL}{_ChapterStart} chapter of
 
72
this manual. 
 
73
 
 
74
\subsubsection*{Installing and Configuring PostgreSQL}
 
75
\index[general]{PostgreSQL!Installing and Configuring }
 
76
\index[general]{Installing and Configuring PostgreSQL }
 
77
\addcontentsline{toc}{subsubsection}{Installing and Configuring PostgreSQL}
 
78
 
 
79
For the details of installing and configuring PostgreSQL, please see the 
 
80
\ilink{Installing and Configuring PostgreSQL}{_ChapterStart10}
 
81
chapter of this manual. 
 
82
 
 
83
\subsubsection*{Installing and Configuring SQLite}
 
84
\index[general]{Installing and Configuring SQLite }
 
85
\index[general]{SQLite!Installing and Configuring }
 
86
\addcontentsline{toc}{subsubsection}{Installing and Configuring SQLite}
 
87
 
 
88
For the details of installing and configuring SQLite, please see the 
 
89
\ilink{Installing and Configuring SQLite}{_ChapterStart33} chapter of
 
90
this manual. 
 
91
 
 
92
\subsubsection*{Internal Bacula Catalog}
 
93
\index[general]{Catalog!Internal Bacula }
 
94
\index[general]{Internal Bacula Catalog }
 
95
\addcontentsline{toc}{subsubsection}{Internal Bacula Catalog}
 
96
 
 
97
Please see the 
 
98
\ilink{Internal Bacula Database}{_ChapterStart42} chapter of this
 
99
manual for more details. 
 
100
 
 
101
\subsubsection*{Database Table Design}
 
102
\index[general]{Design!Database Table }
 
103
\index[general]{Database Table Design }
 
104
\addcontentsline{toc}{subsubsection}{Database Table Design}
 
105
 
 
106
All discussions that follow pertain to the MySQL database. The details for the
 
107
PostgreSQL and SQLite databases are essentially identical except for that all
 
108
fields in the SQLite database are stored as ASCII text and some of the
 
109
database creation statements are a bit different. The details of the internal
 
110
Bacula catalog are not discussed here. 
 
111
 
 
112
Because the Catalog database may contain very large amounts of data for large
 
113
sites, we have made a modest attempt to normalize the data tables to reduce
 
114
redundant information. While reducing the size of the database significantly,
 
115
it does, unfortunately, add some complications to the structures. 
 
116
 
 
117
In simple terms, the Catalog database must contain a record of all Jobs run by
 
118
Bacula, and for each Job, it must maintain a list of all files saved, with
 
119
their File Attributes (permissions, create date, ...), and the location and
 
120
Media on which the file is stored. This is seemingly a simple task, but it
 
121
represents a huge amount interlinked data. Note: the list of files and their
 
122
attributes is not maintained when using the internal Bacula database. The data
 
123
stored in the File records, which allows the user or administrator to obtain a
 
124
list of all files backed up during a job, is by far the largest volume of
 
125
information put into the Catalog database. 
 
126
 
 
127
Although the Catalog database has been designed to handle backup data for
 
128
multiple clients, some users may want to maintain multiple databases, one for
 
129
each machine to be backed up. This reduces the risk of confusion of accidental
 
130
restoring a file to the wrong machine as well as reducing the amount of data
 
131
in a single database, thus increasing efficiency and reducing the impact of a
 
132
lost or damaged database. 
 
133
 
 
134
\subsection*{Sequence of Creation of Records for a Save Job}
 
135
\index[general]{Sequence of Creation of Records for a Save Job }
 
136
\index[general]{Job!Sequence of Creation of Records for a Save }
 
137
\addcontentsline{toc}{subsection}{Sequence of Creation of Records for a Save
 
138
Job}
 
139
 
 
140
Start with StartDate, ClientName, Filename, Path, Attributes, MediaName,
 
141
MediaCoordinates. (PartNumber, NumParts). In the steps below, ``Create new''
 
142
means to create a new record whether or not it is unique. ``Create unique''
 
143
means each record in the database should be unique. Thus, one must first
 
144
search to see if the record exists, and only if not should a new one be
 
145
created, otherwise the existing RecordId should be used. 
 
146
 
 
147
\begin{enumerate}
 
148
\item Create new Job record with StartDate; save JobId  
 
149
\item Create unique Media record; save MediaId  
 
150
\item Create unique Client record; save ClientId  
 
151
\item Create unique Filename record; save FilenameId  
 
152
\item Create unique Path record; save PathId  
 
153
\item Create unique Attribute record; save AttributeId  
 
154
   store ClientId, FilenameId, PathId, and Attributes  
 
155
\item Create new File record  
 
156
   store JobId, AttributeId, MediaCoordinates, etc  
 
157
\item Repeat steps 4 through 8 for each file  
 
158
\item Create a JobMedia record; save MediaId  
 
159
\item Update Job record filling in EndDate and other Job statistics 
 
160
   \end{enumerate}
 
161
 
 
162
\subsection*{Database Tables}
 
163
\index[general]{Database Tables }
 
164
\index[general]{Tables!Database }
 
165
\addcontentsline{toc}{subsection}{Database Tables}
 
166
 
 
167
\addcontentsline{lot}{table}{Filename Table Layout}
 
168
\begin{longtable}{|l|l|l|}
 
169
 \hline 
 
170
\multicolumn{3}{|l| }{\bf Filename  } \\
 
171
 \hline 
 
172
\multicolumn{1}{|c| }{\bf Column Name } & \multicolumn{1}{l| }{\bf Data Type }
 
173
& \multicolumn{1}{l| }{\bf Remark  } \\
 
174
 \hline 
 
175
{FilenameId } & {integer  } & {Primary Key  } \\
 
176
 \hline 
 
177
{Name  } & {Blob  } & {Filename }
 
178
\\ \hline 
 
179
 
 
180
\end{longtable}
 
181
 
 
182
The {\bf Filename} table shown above contains the name of each file backed up
 
183
with the path removed. If different directories or machines contain the same
 
184
filename, only one copy will be saved in this table. 
 
185
 
 
186
 
187
 
 
188
\addcontentsline{lot}{table}{Path Table Layout}
 
189
\begin{longtable}{|l|l|l|}
 
190
 \hline 
 
191
\multicolumn{3}{|l| }{\bf Path  } \\
 
192
 \hline 
 
193
\multicolumn{1}{|c| }{\bf Column Name } & \multicolumn{1}{c| }{\bf Data Type 
 
194
} & \multicolumn{1}{c| }{\bf Remark  } \\
 
195
 \hline 
 
196
{PathId  } & {integer  } & {Primary Key  } \\
 
197
 \hline 
 
198
{Path  } & {Blob } & {Full Path }
 
199
\\ \hline 
 
200
 
 
201
\end{longtable}
 
202
 
 
203
The {\bf Path} table contains shown above the path or directory names of all
 
204
directories on the system or systems. The filename and any MSDOS disk name are
 
205
stripped off. As with the filename, only one copy of each directory name is
 
206
kept regardless of how many machines or drives have the same directory. These
 
207
path names should be stored in Unix path name format. 
 
208
 
 
209
Some simple testing on a Linux file system indicates that separating the
 
210
filename and the path may be more complication than is warranted by the space
 
211
savings. For example, this system has a total of 89,097 files, 60,467 of which
 
212
have unique filenames, and there are 4,374 unique paths. 
 
213
 
 
214
Finding all those files and doing two stats() per file takes an average wall
 
215
clock time of 1 min 35 seconds on a 400MHz machine running RedHat 6.1 Linux. 
 
216
 
 
217
Finding all those files and putting them directly into a MySQL database with
 
218
the path and filename defined as TEXT, which is variable length up to 65,535
 
219
characters takes 19 mins 31 seconds and creates a 27.6 MByte database. 
 
220
 
 
221
Doing the same thing, but inserting them into Blob fields with the filename
 
222
indexed on the first 30 characters and the path name indexed on the 255 (max)
 
223
characters takes 5 mins 18 seconds and creates a 5.24 MB database. Rerunning
 
224
the job (with the database already created) takes about 2 mins 50 seconds. 
 
225
 
 
226
Running the same as the last one (Path and Filename Blob), but Filename
 
227
indexed on the first 30 characters and the Path on the first 50 characters
 
228
(linear search done there after) takes 5 mins on the average and creates a 3.4
 
229
MB database. Rerunning with the data already in the DB takes 3 mins 35
 
230
seconds. 
 
231
 
 
232
Finally, saving only the full path name rather than splitting the path and the
 
233
file, and indexing it on the first 50 characters takes 6 mins 43 seconds and
 
234
creates a 7.35 MB database. 
 
235
 
 
236
 
237
 
 
238
\addcontentsline{lot}{table}{File Table Layout}
 
239
\begin{longtable}{|l|l|l|}
 
240
 \hline 
 
241
\multicolumn{3}{|l| }{\bf File  } \\
 
242
 \hline 
 
243
\multicolumn{1}{|c| }{\bf Column Name  } & \multicolumn{1}{c| }{\bf Data Type
 
244
} & \multicolumn{1}{c| }{\bf Remark  } \\
 
245
 \hline 
 
246
{FileId  } & {integer  } & {Primary Key  } \\
 
247
 \hline 
 
248
{FileIndex  } & {integer  } & {The sequential file number in the Job  } \\
 
249
 \hline 
 
250
{JobId  } & {integer  } & {Link to Job Record  } \\
 
251
 \hline 
 
252
{PathId  } & {integer  } & {Link to Path Record  } \\
 
253
 \hline 
 
254
{FilenameId  } & {integer  } & {Link to Filename Record  } \\
 
255
 \hline 
 
256
{MarkId  } & {integer  } & {Used to mark files during Verify Jobs  } \\
 
257
 \hline 
 
258
{LStat  } & {tinyblob } & {File attributes in base64 encoding  } \\
 
259
 \hline 
 
260
{MD5  } & {tinyblob } & {MD5 signature in base64 encoding }
 
261
\\ \hline 
 
262
 
 
263
\end{longtable}
 
264
 
 
265
The {\bf File} table shown above contains one entry for each file backed up by
 
266
Bacula. Thus a file that is backed up multiple times (as is normal) will have
 
267
multiple entries in the File table. This will probably be the table with the
 
268
most number of records. Consequently, it is essential to keep the size of this
 
269
record to an absolute minimum. At the same time, this table must contain all
 
270
the information (or pointers to the information) about the file and where it
 
271
is backed up. Since a file may be backed up many times without having changed,
 
272
the path and filename are stored in separate tables. 
 
273
 
 
274
This table contains by far the largest amount of information in the Catalog
 
275
database, both from the stand point of number of records, and the stand point
 
276
of total database size. As a consequence, the user must take care to
 
277
periodically reduce the number of File records using the {\bf retention}
 
278
command in the Console program. 
 
279
 
 
280
 
281
 
 
282
\addcontentsline{lot}{table}{Job Table Layout}
 
283
\begin{longtable}{|l|l|p{2.5in}|}
 
284
 \hline 
 
285
\multicolumn{3}{|l| }{\bf Job  } \\
 
286
 \hline 
 
287
\multicolumn{1}{|c| }{\bf Column Name  } & \multicolumn{1}{c| }{\bf Data Type
 
288
} & \multicolumn{1}{c| }{\bf Remark  } \\
 
289
 \hline 
 
290
{JobId  } & {integer  } & {Primary Key  } \\
 
291
 \hline 
 
292
{Job  } & {tinyblob } & {Unique Job Name  } \\
 
293
 \hline 
 
294
{Name  } & {tinyblob } & {Job Name  } \\
 
295
 \hline 
 
296
{PurgedFiles  } & {tinyint  } & {Used by Bacula for purging/retention periods 
 
297
} \\
 
298
 \hline 
 
299
{Type  } & {binary(1)  } & {Job Type: Backup, Copy, Clone, Archive, Migration 
 
300
} \\
 
301
 \hline 
 
302
{Level  } & {binary(1)  } & {Job Level  } \\
 
303
 \hline 
 
304
{ClientId  } & {integer  } & {Client index  } \\
 
305
 \hline 
 
306
{JobStatus  } & {binary(1)  } & {Job Termination Status  } \\
 
307
 \hline 
 
308
{SchedTime  } & {datetime } & {Time/date when Job scheduled  } \\
 
309
 \hline 
 
310
{StartTime  } & {datetime } & {Time/date when Job started  } \\
 
311
 \hline 
 
312
{EndTime  } & {datetime } & {Time/date when Job ended  } \\
 
313
 \hline 
 
314
{JobTDate  } & {bigint  } & {Start day in Unix format but 64 bits;  used for
 
315
Retention period.  } \\
 
316
 \hline 
 
317
{VolSessionId  } & {integer  } & {Unique Volume Session ID  } \\
 
318
 \hline 
 
319
{VolSessionTime } & {integer  } & {Unique Volume Session Time  } \\
 
320
 \hline 
 
321
{JobFiles  } & {integer  } & {Number of files saved in Job  } \\
 
322
 \hline 
 
323
{JobBytes  } & {bigint  } & {Number of bytes saved in Job  } \\
 
324
 \hline 
 
325
{JobErrors  } & {integer  } & {Number of errors during Job  } \\
 
326
 \hline 
 
327
{JobMissingFiles } & {integer } & {Number of files not saved (not yet used)  }
 
328
\\
 
329
 \hline 
 
330
{PoolId  } & {integer  } & {Link to Pool Record  } \\
 
331
 \hline 
 
332
{FileSetId  } & {integer  } & {Link to FileSet Record  } \\
 
333
 \hline 
 
334
{PurgedFiles  } & {tiny integer  } & {Set when all File records purged  } \\
 
335
 \hline 
 
336
{HasBase  } & {tiny integer  } & {Set when Base Job run }
 
337
\\ \hline 
 
338
 
 
339
\end{longtable}
 
340
 
 
341
The {\bf Job} table contains one record for each Job run by Bacula. Thus
 
342
normally, there will be one per day per machine added to the database. Note,
 
343
the JobId is used to index Job records in the database, and it often is shown
 
344
to the user in the Console program. However, care must be taken with its use
 
345
as it is not unique from database to database. For example, the user may have
 
346
a database for Client data saved on machine Rufus and another database for
 
347
Client data saved on machine Roxie. In this case, the two database will each
 
348
have JobIds that match those in another database. For a unique reference to a
 
349
Job, see Job below. 
 
350
 
 
351
The Name field of the Job record corresponds to the Name resource record given
 
352
in the Director's configuration file. Thus it is a generic name, and it will
 
353
be normal to find many Jobs (or even all Jobs) with the same Name. 
 
354
 
 
355
The Job field contains a combination of the Name and the schedule time of the
 
356
Job by the Director. Thus for a given Director, even with multiple Catalog
 
357
databases, the Job will contain a unique name that represents the Job. 
 
358
 
 
359
For a given Storage daemon, the VolSessionId and VolSessionTime form a unique
 
360
identification of the Job. This will be the case even if multiple Directors
 
361
are using the same Storage daemon. 
 
362
 
 
363
The Job Type (or simply Type) can have one of the following values: 
 
364
 
 
365
\addcontentsline{lot}{table}{Job Types}
 
366
\begin{longtable}{|l|l|}
 
367
 \hline 
 
368
\multicolumn{1}{|c| }{\bf Value  } & \multicolumn{1}{c| }{\bf Meaning  } \\
 
369
 \hline 
 
370
{B  } & {Backup Job  } \\
 
371
 \hline 
 
372
{V  } & {Verify Job  } \\
 
373
 \hline 
 
374
{R  } & {Restore Job  } \\
 
375
 \hline 
 
376
{C  } & {Console program (not in database)  } \\
 
377
 \hline 
 
378
{D  } & {Admin Job  } \\
 
379
 \hline 
 
380
{A  } & {Archive Job (not implemented) }
 
381
\\ \hline 
 
382
 
 
383
\end{longtable}
 
384
 
 
385
The JobStatus field specifies how the job terminated, and can be one of the
 
386
following: 
 
387
 
 
388
\addcontentsline{lot}{table}{Job Statuses}
 
389
\begin{longtable}{|l|l|}
 
390
 \hline 
 
391
\multicolumn{1}{|c| }{\bf Value  } & \multicolumn{1}{c| }{\bf Meaning  } \\
 
392
 \hline 
 
393
{C  } & {Created but not yet running  } \\
 
394
 \hline 
 
395
{R  } & {Running  } \\
 
396
 \hline 
 
397
{B  } & {Blocked  } \\
 
398
 \hline 
 
399
{T  } & {Terminated normally  } \\
 
400
 \hline 
 
401
{E  } & {Terminated in Error  } \\
 
402
 \hline 
 
403
{e  } & {Non-fatal error  } \\
 
404
 \hline 
 
405
{f  } & {Fatal error  } \\
 
406
 \hline 
 
407
{D  } & {Verify Differences  } \\
 
408
 \hline 
 
409
{A  } & {Canceled by the user  } \\
 
410
 \hline 
 
411
{F  } & {Waiting on the File daemon  } \\
 
412
 \hline 
 
413
{S  } & {Waiting on the Storage daemon  } \\
 
414
 \hline 
 
415
{m  } & {Waiting for a new Volume to be mounted  } \\
 
416
 \hline 
 
417
{M  } & {Waiting for a Mount  } \\
 
418
 \hline 
 
419
{s  } & {Waiting for Storage resource  } \\
 
420
 \hline 
 
421
{j  } & {Waiting for Job resource  } \\
 
422
 \hline 
 
423
{c  } & {Waiting for Client resource  } \\
 
424
 \hline 
 
425
{d  } & {Wating for Maximum jobs  } \\
 
426
 \hline 
 
427
{t  } & {Waiting for Start Time  } \\
 
428
 \hline 
 
429
{p  } & {Waiting for higher priority job to finish }
 
430
\\ \hline 
 
431
 
 
432
\end{longtable}
 
433
 
 
434
 
435
 
 
436
\addcontentsline{lot}{table}{File Sets Table Layout}
 
437
\begin{longtable}{|l|l|l|}
 
438
 \hline 
 
439
\multicolumn{3}{|l| }{\bf FileSet  } \\
 
440
 \hline 
 
441
\multicolumn{1}{|c| }{\bf Column Name  } & \multicolumn{1}{c| }{\bf Data Type\
 
442
\ \ } & \multicolumn{1}{c| }{\bf Remark  } \\
 
443
 \hline 
 
444
{FileSetId  } & {integer  } & {Primary Key  } \\
 
445
 \hline 
 
446
{FileSet  } & {tinyblob  } & {FileSet name  } \\
 
447
 \hline 
 
448
{MD5  } & {tinyblob  } & {MD5 checksum of FileSet  } \\
 
449
 \hline 
 
450
{CreateTime  } & {datetime  } & {Time and date Fileset created }
 
451
\\ \hline 
 
452
 
 
453
\end{longtable}
 
454
 
 
455
The {\bf FileSet} table contains one entry for each FileSet that is used. The
 
456
MD5 signature is kept to ensure that if the user changes anything inside the
 
457
FileSet, it will be detected and the new FileSet will be used. This is
 
458
particularly important when doing an incremental update. If the user deletes a
 
459
file or adds a file, we need to ensure that a Full backup is done prior to the
 
460
next incremental. 
 
461
 
 
462
 
463
 
 
464
\addcontentsline{lot}{table}{JobMedia Table Layout}
 
465
\begin{longtable}{|l|l|p{2.5in}|}
 
466
 \hline 
 
467
\multicolumn{3}{|l| }{\bf JobMedia  } \\
 
468
 \hline 
 
469
\multicolumn{1}{|c| }{\bf Column Name  } & \multicolumn{1}{c| }{\bf Data Type\
 
470
\ \ } & \multicolumn{1}{c| }{\bf Remark  } \\
 
471
 \hline 
 
472
{JobMediaId  } & {integer  } & {Primary Key  } \\
 
473
 \hline 
 
474
{JobId  } & {integer  } & {Link to Job Record  } \\
 
475
 \hline 
 
476
{MediaId  } & {integer  } & {Link to Media Record  } \\
 
477
 \hline 
 
478
{FirstIndex  } & {integer  } & {The index (sequence number)  of the first file
 
479
written for this Job to the Media  } \\
 
480
 \hline 
 
481
{LastIndex  } & {integer  } & {The index  of the last file written for this
 
482
Job to the Media  } \\
 
483
 \hline 
 
484
{StartFile  } & {integer  } & {The physical media (tape)  file number of the
 
485
first block written for this Job  } \\
 
486
 \hline 
 
487
{EndFile  } & {integer  } & {The physical media (tape)  file number of the
 
488
last block written for this Job  } \\
 
489
 \hline 
 
490
{StartBlock  } & {integer  } & {The number of the first  block written for
 
491
this Job  } \\
 
492
 \hline 
 
493
{EndBlock  } & {integer  } & {The number of the last  block written for this
 
494
Job  } \\
 
495
 \hline 
 
496
{VolIndex  } & {integer  } & {The Volume use sequence number  within the Job }
 
497
\\ \hline 
 
498
 
 
499
\end{longtable}
 
500
 
 
501
The {\bf JobMedia} table contains one entry at the following: start of
 
502
the job, start of each new tape file, start of each new tape, end of the
 
503
job.  Since by default, a new tape file is written every 2GB, in general,
 
504
you will have more than 2 JobMedia records per Job.  The number can be
 
505
varied by changing the "Maximum File Size" specified in the Device 
 
506
resource.  This record allows Bacula to efficiently position close to
 
507
(within 2GB) any given file in a backup.  For restoring a full Job,
 
508
these records are not very important, but if you want to retrieve
 
509
a single file that was written near the end of a 100GB backup, the   
 
510
JobMedia records can speed it up by orders of magnitude by permitting
 
511
forward spacing files and blocks rather than reading the whole 100GB
 
512
backup.
 
513
        
 
514
 
 
515
 
 
516
 
517
 
 
518
\addcontentsline{lot}{table}{Media Table Layout}
 
519
\begin{longtable}{|l|l|p{2.4in}|}
 
520
 \hline 
 
521
\multicolumn{3}{|l| }{\bf Media  } \\
 
522
 \hline 
 
523
\multicolumn{1}{|c| }{\bf Column Name  } & \multicolumn{1}{c| }{\bf Data Type\
 
524
\ \ } & \multicolumn{1}{c| }{\bf Remark  } \\
 
525
 \hline 
 
526
{MediaId  } & {integer } & {Primary Key  } \\
 
527
 \hline 
 
528
{VolumeName  } & {tinyblob } & {Volume name  } \\
 
529
 \hline 
 
530
{Slot  } & {integer } & {Autochanger Slot number or zero  } \\
 
531
 \hline 
 
532
{PoolId  } & {integer } & {Link to Pool Record  } \\
 
533
 \hline 
 
534
{MediaType  } & {tinyblob } & {The MediaType supplied by the user  } \\
 
535
 \hline 
 
536
{FirstWritten  } & {datetime } & {Time/date when first written  } \\
 
537
 \hline 
 
538
{LastWritten  } & {datetime } & {Time/date when last written  } \\
 
539
 \hline 
 
540
{LabelDate  } & {datetime } & {Time/date when tape labeled  } \\
 
541
 \hline 
 
542
{VolJobs  } & {integer  } & {Number of jobs written to this media  } \\
 
543
 \hline 
 
544
{VolFiles  } & {integer  } & {Number of files written to this media  } \\
 
545
 \hline 
 
546
{VolBlocks  } & {integer  } & {Number of blocks written to this media  } \\
 
547
 \hline 
 
548
{VolMounts  } & {integer  } & {Number of time media mounted  } \\
 
549
 \hline 
 
550
{VolBytes  } & {bigint  } & {Number of bytes saved in Job  } \\
 
551
 \hline 
 
552
{VolErrors  } & {integer  } & {Number of errors during Job  } \\
 
553
 \hline 
 
554
{VolWrites  } & {integer  } & {Number of writes to media  } \\
 
555
 \hline 
 
556
{MaxVolBytes  } & {bigint } & {Maximum bytes to put on this media  } \\
 
557
 \hline 
 
558
{VolCapacityBytes } & {bigint } & {Capacity estimate for this volume  } \\
 
559
 \hline 
 
560
{VolStatus  } & {enum  } & {Status of media: Full, Archive, Append, Recycle, 
 
561
Read-Only, Disabled, Error, Busy  } \\
 
562
 \hline 
 
563
{Recycle  } & {tinyint  } & {Whether or not Bacula can recycle the Volumes:
 
564
Yes, No  } \\
 
565
 \hline 
 
566
{VolRetention  } & {bigint  } & {64 bit seconds until expiration  } \\
 
567
 \hline 
 
568
{VolUseDuration  } & {bigint  } & {64 bit seconds volume can be used  } \\
 
569
 \hline 
 
570
{MaxVolJobs  } & {integer  } & {maximum jobs to put on Volume  } \\
 
571
 \hline 
 
572
{MaxVolFiles  } & {integer  } & {maximume EOF marks to put on Volume }
 
573
\\ \hline 
 
574
 
 
575
\end{longtable}
 
576
 
 
577
The {\bf Volume} table (internally referred to as the Media table) contains
 
578
one entry for each volume, that is each tape, cassette (8mm, DLT, DAT, ...),
 
579
or file on which information is or was backed up. There is one Volume record
 
580
created for each of the NumVols specified in the Pool resource record. 
 
581
 
 
582
 
583
 
 
584
\addcontentsline{lot}{table}{Pool Table Layout}
 
585
\begin{longtable}{|l|l|p{2.4in}|}
 
586
 \hline 
 
587
\multicolumn{3}{|l| }{\bf Pool  } \\
 
588
 \hline 
 
589
\multicolumn{1}{|c| }{\bf Column Name  } & \multicolumn{1}{c| }{\bf Data Type
 
590
} & \multicolumn{1}{c| }{\bf Remark  } \\
 
591
 \hline 
 
592
{PoolId  } & {integer  } & {Primary Key  } \\
 
593
 \hline 
 
594
{Name  } & {Tinyblob } & {Pool Name  } \\
 
595
 \hline 
 
596
{NumVols  } & {Integer  } & {Number of Volumes in the Pool  } \\
 
597
 \hline 
 
598
{MaxVols  } & {Integer  } & {Maximum Volumes in the Pool  } \\
 
599
 \hline 
 
600
{UseOnce  } & {tinyint  } & {Use volume once  } \\
 
601
 \hline 
 
602
{UseCatalog  } & {tinyint  } & {Set to use catalog  } \\
 
603
 \hline 
 
604
{AcceptAnyVolume } & {tinyint  } & {Accept any volume from Pool  } \\
 
605
 \hline 
 
606
{VolRetention  } & {bigint  } & {64 bit seconds to retain volume  } \\
 
607
 \hline 
 
608
{VolUseDuration  } & {bigint  } & {64 bit seconds volume can be used  } \\
 
609
 \hline 
 
610
{MaxVolJobs  } & {integer  } & {max jobs on volume  } \\
 
611
 \hline 
 
612
{MaxVolFiles  } & {integer  } & {max EOF marks to put on Volume  } \\
 
613
 \hline 
 
614
{MaxVolBytes  } & {bigint  } & {max bytes to write on Volume  } \\
 
615
 \hline 
 
616
{AutoPrune  } & {tinyint  } & {yes|no for autopruning  } \\
 
617
 \hline 
 
618
{Recycle  } & {tinyint  } & {yes|no for allowing auto recycling of Volume  }
 
619
\\
 
620
 \hline 
 
621
{PoolType  } & {enum  } & {Backup, Copy, Cloned, Archive, Migration  } \\
 
622
 \hline 
 
623
{LabelFormat  } & {Tinyblob } & {Label format }
 
624
\\ \hline 
 
625
 
 
626
\end{longtable}
 
627
 
 
628
The {\bf Pool} table contains one entry for each media pool controlled by
 
629
Bacula in this database. One media record exists for each of the NumVols
 
630
contained in the Pool. The PoolType is a Bacula defined keyword. The MediaType
 
631
is defined by the administrator, and corresponds to the MediaType specified in
 
632
the Director's Storage definition record. The CurrentVol is the sequence
 
633
number of the Media record for the current volume. 
 
634
 
 
635
 
636
 
 
637
\addcontentsline{lot}{table}{Client Table Layout}
 
638
\begin{longtable}{|l|l|l|}
 
639
 \hline 
 
640
\multicolumn{3}{|l| }{\bf Client  } \\
 
641
 \hline 
 
642
\multicolumn{1}{|c| }{\bf Column Name } & \multicolumn{1}{c| }{\bf Data Type 
 
643
} & \multicolumn{1}{c| }{\bf Remark  } \\
 
644
 \hline 
 
645
{ClientId  } & {integer  } & {Primary Key  } \\
 
646
 \hline 
 
647
{Name  } & {TinyBlob  } & {File Services Name  } \\
 
648
 \hline 
 
649
{UName  } & {TinyBlob  } & {uname -a from Client (not yet used)  } \\
 
650
 \hline 
 
651
{AutoPrune  } & {tinyint  } & {yes|no for autopruning  } \\
 
652
 \hline 
 
653
{FileRetention  } & {bigint  } & {64 bit seconds to retain Files  } \\
 
654
 \hline 
 
655
{JobRetention  } & {bigint  } & {64 bit seconds to retain Job }
 
656
\\ \hline 
 
657
 
 
658
\end{longtable}
 
659
 
 
660
The {\bf Client} table contains one entry for each machine backed up by Bacula
 
661
in this database. Normally the Name is a fully qualified domain name. 
 
662
 
 
663
 
664
 
 
665
\addcontentsline{lot}{table}{Unsaved Files Table Layout}
 
666
\begin{longtable}{|l|l|l|}
 
667
 \hline 
 
668
\multicolumn{3}{|l| }{\bf UnsavedFiles  } \\
 
669
 \hline 
 
670
\multicolumn{1}{|c| }{\bf Column Name } & \multicolumn{1}{c| }{\bf Data Type 
 
671
} & \multicolumn{1}{c| }{\bf Remark  } \\
 
672
 \hline 
 
673
{UnsavedId  } & {integer  } & {Primary Key  } \\
 
674
 \hline 
 
675
{JobId  } & {integer  } & {JobId corresponding to this record  } \\
 
676
 \hline 
 
677
{PathId  } & {integer  } & {Id of path  } \\
 
678
 \hline 
 
679
{FilenameId  } & {integer  } & {Id of filename }
 
680
\\ \hline 
 
681
 
 
682
\end{longtable}
 
683
 
 
684
The {\bf UnsavedFiles} table contains one entry for each file that was not
 
685
saved. Note! This record is not yet implemented. 
 
686
 
 
687
 
688
 
 
689
\addcontentsline{lot}{table}{Counter Table Layout}
 
690
\begin{longtable}{|l|l|l|}
 
691
 \hline 
 
692
\multicolumn{3}{|l| }{\bf Counter  } \\
 
693
 \hline 
 
694
\multicolumn{1}{|c| }{\bf Column Name } & \multicolumn{1}{c| }{\bf Data Type 
 
695
} & \multicolumn{1}{c| }{\bf Remark  } \\
 
696
 \hline 
 
697
{Counter  } & {tinyblob  } & {Counter name  } \\
 
698
 \hline 
 
699
{MinValue  } & {integer } & {Start/Min value for counter  } \\
 
700
 \hline 
 
701
{MaxValue  } & {integer } & {Max value for counter  } \\
 
702
 \hline 
 
703
{CurrentValue  } & {integer } & {Current counter value  } \\
 
704
 \hline 
 
705
{WrapCounter  } & {tinyblob  } & {Name of another counter }
 
706
\\ \hline 
 
707
 
 
708
\end{longtable}
 
709
 
 
710
The {\bf Counter} table contains one entry for each permanent counter defined
 
711
by the user. 
 
712
 
 
713
 
714
 
 
715
\addcontentsline{lot}{table}{Version Table Layout}
 
716
\begin{longtable}{|l|l|l|}
 
717
 \hline 
 
718
\multicolumn{3}{|l| }{\bf Version  } \\
 
719
 \hline 
 
720
\multicolumn{1}{|c| }{\bf Column Name } & \multicolumn{1}{c| }{\bf Data Type 
 
721
} & \multicolumn{1}{c| }{\bf Remark  } \\
 
722
 \hline 
 
723
{VersionId  } & {integer  } & {Primary Key }
 
724
\\ \hline 
 
725
 
 
726
\end{longtable}
 
727
 
 
728
The {\bf Version} table defines the Bacula database version number. Bacula
 
729
checks this number before reading the database to ensure that it is compatible
 
730
with the Bacula binary file. 
 
731
 
 
732
 
733
 
 
734
\addcontentsline{lot}{table}{Base Files Table Layout}
 
735
\begin{longtable}{|l|l|l|}
 
736
 \hline 
 
737
\multicolumn{3}{|l| }{\bf BaseFiles  } \\
 
738
 \hline 
 
739
\multicolumn{1}{|c| }{\bf Column Name } & \multicolumn{1}{c| }{\bf Data Type 
 
740
} & \multicolumn{1}{c| }{\bf Remark  } \\
 
741
 \hline 
 
742
{BaseId  } & {integer  } & {Primary Key  } \\
 
743
 \hline 
 
744
{BaseJobId  } & {integer  } & {JobId of Base Job  } \\
 
745
 \hline 
 
746
{JobId  } & {integer  } & {Reference to Job  } \\
 
747
 \hline 
 
748
{FileId  } & {integer  } & {Reference to File  } \\
 
749
 \hline 
 
750
{FileIndex  } & {integer  } & {File Index number }
 
751
\\ \hline 
 
752
 
 
753
\end{longtable}
 
754
 
 
755
The {\bf BaseFiles} table contains all the File references for a particular
 
756
JobId that point to a Base file -- i.e. they were previously saved and hence
 
757
were not saved in the current JobId but in BaseJobId under FileId. FileIndex
 
758
is the index of the file, and is used for optimization of Restore jobs to
 
759
prevent the need to read the FileId record when creating the in memory tree.
 
760
This record is not yet implemented. 
 
761
 
 
762
 
763
 
 
764
\subsubsection*{MySQL Table Definition}
 
765
\index[general]{MySQL Table Definition }
 
766
\index[general]{Definition!MySQL Table }
 
767
\addcontentsline{toc}{subsubsection}{MySQL Table Definition}
 
768
 
 
769
The commands used to create the MySQL tables are as follows: 
 
770
 
 
771
\footnotesize
 
772
\begin{verbatim}
 
773
USE bacula;
 
774
CREATE TABLE Filename (
 
775
  FilenameId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
 
776
  Name BLOB NOT NULL,
 
777
  PRIMARY KEY(FilenameId),
 
778
  INDEX (Name(30))
 
779
  );
 
780
CREATE TABLE Path (
 
781
   PathId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
 
782
   Path BLOB NOT NULL,
 
783
   PRIMARY KEY(PathId),
 
784
   INDEX (Path(50))
 
785
   );
 
786
CREATE TABLE File (
 
787
   FileId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
 
788
   FileIndex INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
789
   JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
 
790
   PathId INTEGER UNSIGNED NOT NULL REFERENCES Path,
 
791
   FilenameId INTEGER UNSIGNED NOT NULL REFERENCES Filename,
 
792
   MarkId INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
793
   LStat TINYBLOB NOT NULL,
 
794
   MD5 TINYBLOB NOT NULL,
 
795
   PRIMARY KEY(FileId),
 
796
   INDEX (JobId),
 
797
   INDEX (PathId),
 
798
   INDEX (FilenameId)
 
799
   );
 
800
CREATE TABLE Job (
 
801
   JobId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
 
802
   Job TINYBLOB NOT NULL,
 
803
   Name TINYBLOB NOT NULL,
 
804
   Type BINARY(1) NOT NULL,
 
805
   Level BINARY(1) NOT NULL,
 
806
   ClientId INTEGER NOT NULL REFERENCES Client,
 
807
   JobStatus BINARY(1) NOT NULL,
 
808
   SchedTime DATETIME NOT NULL,
 
809
   StartTime DATETIME NOT NULL,
 
810
   EndTime DATETIME NOT NULL,
 
811
   JobTDate BIGINT UNSIGNED NOT NULL,
 
812
   VolSessionId INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
813
   VolSessionTime INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
814
   JobFiles INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
815
   JobBytes BIGINT UNSIGNED NOT NULL,
 
816
   JobErrors INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
817
   JobMissingFiles INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
818
   PoolId INTEGER UNSIGNED NOT NULL REFERENCES Pool,
 
819
   FileSetId INTEGER UNSIGNED NOT NULL REFERENCES FileSet,
 
820
   PurgedFiles TINYINT NOT NULL DEFAULT 0,
 
821
   HasBase TINYINT NOT NULL DEFAULT 0,
 
822
   PRIMARY KEY(JobId),
 
823
   INDEX (Name(128))
 
824
   );
 
825
CREATE TABLE FileSet (
 
826
   FileSetId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
 
827
   FileSet TINYBLOB NOT NULL,
 
828
   MD5 TINYBLOB NOT NULL,
 
829
   CreateTime DATETIME NOT NULL,
 
830
   PRIMARY KEY(FileSetId)
 
831
   );
 
832
CREATE TABLE JobMedia (
 
833
   JobMediaId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
 
834
   JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
 
835
   MediaId INTEGER UNSIGNED NOT NULL REFERENCES Media,
 
836
   FirstIndex INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
837
   LastIndex INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
838
   StartFile INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
839
   EndFile INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
840
   StartBlock INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
841
   EndBlock INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
842
   VolIndex INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
843
   PRIMARY KEY(JobMediaId),
 
844
   INDEX (JobId, MediaId)
 
845
   );
 
846
CREATE TABLE Media (
 
847
   MediaId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
 
848
   VolumeName TINYBLOB NOT NULL,
 
849
   Slot INTEGER NOT NULL DEFAULT 0,
 
850
   PoolId INTEGER UNSIGNED NOT NULL REFERENCES Pool,
 
851
   MediaType TINYBLOB NOT NULL,
 
852
   FirstWritten DATETIME NOT NULL,
 
853
   LastWritten DATETIME NOT NULL,
 
854
   LabelDate DATETIME NOT NULL,
 
855
   VolJobs INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
856
   VolFiles INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
857
   VolBlocks INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
858
   VolMounts INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
859
   VolBytes BIGINT UNSIGNED NOT NULL DEFAULT 0,
 
860
   VolErrors INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
861
   VolWrites INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
862
   VolCapacityBytes BIGINT UNSIGNED NOT NULL,
 
863
   VolStatus ENUM('Full', 'Archive', 'Append', 'Recycle', 'Purged',
 
864
    'Read-Only', 'Disabled', 'Error', 'Busy', 'Used', 'Cleaning') NOT NULL,
 
865
   Recycle TINYINT NOT NULL DEFAULT 0,
 
866
   VolRetention BIGINT UNSIGNED NOT NULL DEFAULT 0,
 
867
   VolUseDuration BIGINT UNSIGNED NOT NULL DEFAULT 0,
 
868
   MaxVolJobs INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
869
   MaxVolFiles INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
870
   MaxVolBytes BIGINT UNSIGNED NOT NULL DEFAULT 0,
 
871
   InChanger TINYINT NOT NULL DEFAULT 0,
 
872
   MediaAddressing TINYINT NOT NULL DEFAULT 0,
 
873
   VolReadTime BIGINT UNSIGNED NOT NULL DEFAULT 0,
 
874
   VolWriteTime BIGINT UNSIGNED NOT NULL DEFAULT 0,
 
875
   PRIMARY KEY(MediaId),
 
876
   INDEX (PoolId)
 
877
   );
 
878
CREATE TABLE Pool (
 
879
   PoolId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
 
880
   Name TINYBLOB NOT NULL,
 
881
   NumVols INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
882
   MaxVols INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
883
   UseOnce TINYINT NOT NULL,
 
884
   UseCatalog TINYINT NOT NULL,
 
885
   AcceptAnyVolume TINYINT DEFAULT 0,
 
886
   VolRetention BIGINT UNSIGNED NOT NULL,
 
887
   VolUseDuration BIGINT UNSIGNED NOT NULL,
 
888
   MaxVolJobs INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
889
   MaxVolFiles INTEGER UNSIGNED NOT NULL DEFAULT 0,
 
890
   MaxVolBytes BIGINT UNSIGNED NOT NULL,
 
891
   AutoPrune TINYINT DEFAULT 0,
 
892
   Recycle TINYINT DEFAULT 0,
 
893
   PoolType ENUM('Backup', 'Copy', 'Cloned', 'Archive', 'Migration', 'Scratch') NOT NULL,
 
894
   LabelFormat TINYBLOB,
 
895
   Enabled TINYINT DEFAULT 1,
 
896
   ScratchPoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool,
 
897
   RecyclePoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool,
 
898
   UNIQUE (Name(128)),
 
899
   PRIMARY KEY (PoolId)
 
900
   );
 
901
CREATE TABLE Client (
 
902
   ClientId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
 
903
   Name TINYBLOB NOT NULL,
 
904
   Uname TINYBLOB NOT NULL,       /* full uname -a of client */
 
905
   AutoPrune TINYINT DEFAULT 0,
 
906
   FileRetention BIGINT UNSIGNED NOT NULL,
 
907
   JobRetention  BIGINT UNSIGNED NOT NULL,
 
908
   UNIQUE (Name(128)),
 
909
   PRIMARY KEY(ClientId)
 
910
   );
 
911
CREATE TABLE BaseFiles (
 
912
   BaseId INTEGER UNSIGNED AUTO_INCREMENT,
 
913
   BaseJobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
 
914
   JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
 
915
   FileId INTEGER UNSIGNED NOT NULL REFERENCES File,
 
916
   FileIndex INTEGER UNSIGNED,
 
917
   PRIMARY KEY(BaseId)
 
918
   );
 
919
CREATE TABLE UnsavedFiles (
 
920
   UnsavedId INTEGER UNSIGNED AUTO_INCREMENT,
 
921
   JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
 
922
   PathId INTEGER UNSIGNED NOT NULL REFERENCES Path,
 
923
   FilenameId INTEGER UNSIGNED NOT NULL REFERENCES Filename,
 
924
   PRIMARY KEY (UnsavedId)
 
925
   );
 
926
CREATE TABLE Version (
 
927
   VersionId INTEGER UNSIGNED NOT NULL
 
928
   );
 
929
-- Initialize Version
 
930
INSERT INTO Version (VersionId) VALUES (7);
 
931
CREATE TABLE Counters (
 
932
   Counter TINYBLOB NOT NULL,
 
933
   MinValue INTEGER,
 
934
   MaxValue INTEGER,
 
935
   CurrentValue INTEGER,
 
936
   WrapCounter TINYBLOB NOT NULL,
 
937
   PRIMARY KEY (Counter(128))
 
938
   );
 
939
\end{verbatim}
 
940
\normalsize