]> git.ozlabs.org Git - ccan/blob - ccan/tdb2/doc/design.lyx
276832ead7bd9582b94cf94f32fc982b4cbf7d8d
[ccan] / ccan / tdb2 / doc / design.lyx
1 #LyX 1.6.5 created this file. For more info see http://www.lyx.org/
2 \lyxformat 345
3 \begin_document
4 \begin_header
5 \textclass article
6 \use_default_options true
7 \language english
8 \inputencoding auto
9 \font_roman default
10 \font_sans default
11 \font_typewriter default
12 \font_default_family default
13 \font_sc false
14 \font_osf false
15 \font_sf_scale 100
16 \font_tt_scale 100
17
18 \graphics default
19 \paperfontsize default
20 \use_hyperref false
21 \papersize default
22 \use_geometry false
23 \use_amsmath 1
24 \use_esint 1
25 \cite_engine basic
26 \use_bibtopic false
27 \paperorientation portrait
28 \secnumdepth 3
29 \tocdepth 3
30 \paragraph_separation indent
31 \defskip medskip
32 \quotes_language english
33 \papercolumns 1
34 \papersides 1
35 \paperpagestyle default
36 \tracking_changes true
37 \output_changes true
38 \author "Rusty Russell,,," 
39 \author "" 
40 \end_header
41
42 \begin_body
43
44 \begin_layout Title
45 TDB2: A Redesigning The Trivial DataBase
46 \end_layout
47
48 \begin_layout Author
49 Rusty Russell, IBM Corporation
50 \end_layout
51
52 \begin_layout Date
53
54 \change_deleted 0 1283307542
55 26-July
56 \change_inserted 0 1283307544
57 1-September
58 \change_unchanged
59 -2010
60 \end_layout
61
62 \begin_layout Abstract
63 The Trivial DataBase on-disk format is 32 bits; with usage cases heading
64  towards the 4G limit, that must change.
65  This required breakage provides an opportunity to revisit TDB's other design
66  decisions and reassess them.
67 \end_layout
68
69 \begin_layout Section
70 Introduction
71 \end_layout
72
73 \begin_layout Standard
74 The Trivial DataBase was originally written by Andrew Tridgell as a simple
75  key/data pair storage system with the same API as dbm, but allowing multiple
76  readers and writers while being small enough (< 1000 lines of C) to include
77  in SAMBA.
78  The simple design created in 1999 has proven surprisingly robust and performant
79 , used in Samba versions 3 and 4 as well as numerous other projects.
80  Its useful life was greatly increased by the (backwards-compatible!) addition
81  of transaction support in 2005.
82 \end_layout
83
84 \begin_layout Standard
85 The wider variety and greater demands of TDB-using code has lead to some
86  organic growth of the API, as well as some compromises on the implementation.
87  None of these, by themselves, are seen as show-stoppers, but the cumulative
88  effect is to a loss of elegance over the initial, simple TDB implementation.
89  Here is a table of the approximate number of lines of implementation code
90  and number of API functions at the end of each year:
91 \end_layout
92
93 \begin_layout Standard
94 \begin_inset Tabular
95 <lyxtabular version="3" rows="12" columns="3">
96 <features>
97 <column alignment="center" valignment="top" width="0">
98 <column alignment="center" valignment="top" width="0">
99 <column alignment="center" valignment="top" width="0">
100 <row>
101 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
102 \begin_inset Text
103
104 \begin_layout Plain Layout
105 Year End
106 \end_layout
107
108 \end_inset
109 </cell>
110 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
111 \begin_inset Text
112
113 \begin_layout Plain Layout
114 API Functions
115 \end_layout
116
117 \end_inset
118 </cell>
119 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
120 \begin_inset Text
121
122 \begin_layout Plain Layout
123 Lines of C Code Implementation
124 \end_layout
125
126 \end_inset
127 </cell>
128 </row>
129 <row>
130 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
131 \begin_inset Text
132
133 \begin_layout Plain Layout
134 1999
135 \end_layout
136
137 \end_inset
138 </cell>
139 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
140 \begin_inset Text
141
142 \begin_layout Plain Layout
143 13
144 \end_layout
145
146 \end_inset
147 </cell>
148 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
149 \begin_inset Text
150
151 \begin_layout Plain Layout
152 1195
153 \end_layout
154
155 \end_inset
156 </cell>
157 </row>
158 <row>
159 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
160 \begin_inset Text
161
162 \begin_layout Plain Layout
163 2000
164 \end_layout
165
166 \end_inset
167 </cell>
168 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
169 \begin_inset Text
170
171 \begin_layout Plain Layout
172 24
173 \end_layout
174
175 \end_inset
176 </cell>
177 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
178 \begin_inset Text
179
180 \begin_layout Plain Layout
181 1725
182 \end_layout
183
184 \end_inset
185 </cell>
186 </row>
187 <row>
188 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
189 \begin_inset Text
190
191 \begin_layout Plain Layout
192 2001
193 \end_layout
194
195 \end_inset
196 </cell>
197 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
198 \begin_inset Text
199
200 \begin_layout Plain Layout
201 32
202 \end_layout
203
204 \end_inset
205 </cell>
206 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
207 \begin_inset Text
208
209 \begin_layout Plain Layout
210 2228
211 \end_layout
212
213 \end_inset
214 </cell>
215 </row>
216 <row>
217 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
218 \begin_inset Text
219
220 \begin_layout Plain Layout
221 2002
222 \end_layout
223
224 \end_inset
225 </cell>
226 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
227 \begin_inset Text
228
229 \begin_layout Plain Layout
230 35
231 \end_layout
232
233 \end_inset
234 </cell>
235 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
236 \begin_inset Text
237
238 \begin_layout Plain Layout
239 2481
240 \end_layout
241
242 \end_inset
243 </cell>
244 </row>
245 <row>
246 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
247 \begin_inset Text
248
249 \begin_layout Plain Layout
250 2003
251 \end_layout
252
253 \end_inset
254 </cell>
255 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
256 \begin_inset Text
257
258 \begin_layout Plain Layout
259 35
260 \end_layout
261
262 \end_inset
263 </cell>
264 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
265 \begin_inset Text
266
267 \begin_layout Plain Layout
268 2552
269 \end_layout
270
271 \end_inset
272 </cell>
273 </row>
274 <row>
275 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
276 \begin_inset Text
277
278 \begin_layout Plain Layout
279 2004
280 \end_layout
281
282 \end_inset
283 </cell>
284 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
285 \begin_inset Text
286
287 \begin_layout Plain Layout
288 40
289 \end_layout
290
291 \end_inset
292 </cell>
293 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
294 \begin_inset Text
295
296 \begin_layout Plain Layout
297 2584
298 \end_layout
299
300 \end_inset
301 </cell>
302 </row>
303 <row>
304 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
305 \begin_inset Text
306
307 \begin_layout Plain Layout
308 2005
309 \end_layout
310
311 \end_inset
312 </cell>
313 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
314 \begin_inset Text
315
316 \begin_layout Plain Layout
317 38
318 \end_layout
319
320 \end_inset
321 </cell>
322 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
323 \begin_inset Text
324
325 \begin_layout Plain Layout
326 2647
327 \end_layout
328
329 \end_inset
330 </cell>
331 </row>
332 <row>
333 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
334 \begin_inset Text
335
336 \begin_layout Plain Layout
337 2006
338 \end_layout
339
340 \end_inset
341 </cell>
342 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
343 \begin_inset Text
344
345 \begin_layout Plain Layout
346 52
347 \end_layout
348
349 \end_inset
350 </cell>
351 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
352 \begin_inset Text
353
354 \begin_layout Plain Layout
355 3754
356 \end_layout
357
358 \end_inset
359 </cell>
360 </row>
361 <row>
362 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
363 \begin_inset Text
364
365 \begin_layout Plain Layout
366 2007
367 \end_layout
368
369 \end_inset
370 </cell>
371 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
372 \begin_inset Text
373
374 \begin_layout Plain Layout
375 66
376 \end_layout
377
378 \end_inset
379 </cell>
380 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
381 \begin_inset Text
382
383 \begin_layout Plain Layout
384 4398
385 \end_layout
386
387 \end_inset
388 </cell>
389 </row>
390 <row>
391 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
392 \begin_inset Text
393
394 \begin_layout Plain Layout
395 2008
396 \end_layout
397
398 \end_inset
399 </cell>
400 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
401 \begin_inset Text
402
403 \begin_layout Plain Layout
404 71
405 \end_layout
406
407 \end_inset
408 </cell>
409 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
410 \begin_inset Text
411
412 \begin_layout Plain Layout
413 4768
414 \end_layout
415
416 \end_inset
417 </cell>
418 </row>
419 <row>
420 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
421 \begin_inset Text
422
423 \begin_layout Plain Layout
424 2009
425 \end_layout
426
427 \end_inset
428 </cell>
429 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
430 \begin_inset Text
431
432 \begin_layout Plain Layout
433 73
434 \end_layout
435
436 \end_inset
437 </cell>
438 <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
439 \begin_inset Text
440
441 \begin_layout Plain Layout
442 5715
443 \end_layout
444
445 \end_inset
446 </cell>
447 </row>
448 </lyxtabular>
449
450 \end_inset
451
452
453 \end_layout
454
455 \begin_layout Standard
456 This review is an attempt to catalog and address all the known issues with
457  TDB and create solutions which address the problems without significantly
458  increasing complexity; all involved are far too aware of the dangers of
459  second system syndrome in rewriting a successful project like this.
460 \end_layout
461
462 \begin_layout Section
463 API Issues
464 \end_layout
465
466 \begin_layout Subsection
467 tdb_open_ex Is Not Expandable
468 \end_layout
469
470 \begin_layout Standard
471 The tdb_open() call was expanded to tdb_open_ex(), which added an optional
472  hashing function and an optional logging function argument.
473  Additional arguments to open would require the introduction of a tdb_open_ex2
474  call etc.
475 \end_layout
476
477 \begin_layout Subsubsection
478 Proposed Solution
479 \end_layout
480
481 \begin_layout Standard
482 tdb_open() will take a linked-list of attributes:
483 \end_layout
484
485 \begin_layout LyX-Code
486 enum tdb_attribute {
487 \end_layout
488
489 \begin_layout LyX-Code
490     TDB_ATTRIBUTE_LOG = 0,
491 \end_layout
492
493 \begin_layout LyX-Code
494     TDB_ATTRIBUTE_HASH = 1
495 \end_layout
496
497 \begin_layout LyX-Code
498 };
499 \end_layout
500
501 \begin_layout LyX-Code
502 struct tdb_attribute_base {
503 \end_layout
504
505 \begin_layout LyX-Code
506     enum tdb_attribute attr;
507 \end_layout
508
509 \begin_layout LyX-Code
510     union tdb_attribute *next;
511 \end_layout
512
513 \begin_layout LyX-Code
514 };
515 \end_layout
516
517 \begin_layout LyX-Code
518 struct tdb_attribute_log {
519 \end_layout
520
521 \begin_layout LyX-Code
522     struct tdb_attribute_base base; /* .attr = TDB_ATTRIBUTE_LOG */
523 \end_layout
524
525 \begin_layout LyX-Code
526     tdb_log_func log_fn;
527 \end_layout
528
529 \begin_layout LyX-Code
530     void *log_private;
531 \end_layout
532
533 \begin_layout LyX-Code
534 };
535 \end_layout
536
537 \begin_layout LyX-Code
538 struct tdb_attribute_hash {
539 \end_layout
540
541 \begin_layout LyX-Code
542     struct tdb_attribute_base base; /* .attr = TDB_ATTRIBUTE_HASH */
543 \end_layout
544
545 \begin_layout LyX-Code
546     tdb_hash_func hash_fn;
547 \end_layout
548
549 \begin_layout LyX-Code
550     void *hash_private;
551 \end_layout
552
553 \begin_layout LyX-Code
554 };
555 \end_layout
556
557 \begin_layout LyX-Code
558 union tdb_attribute {
559 \end_layout
560
561 \begin_layout LyX-Code
562     struct tdb_attribute_base base;
563 \end_layout
564
565 \begin_layout LyX-Code
566     struct tdb_attribute_log log;
567 \end_layout
568
569 \begin_layout LyX-Code
570     struct tdb_attribute_hash hash;
571 \end_layout
572
573 \begin_layout LyX-Code
574 };
575 \end_layout
576
577 \begin_layout Standard
578 This allows future attributes to be added, even if this expands the size
579  of the union.
580 \end_layout
581
582 \begin_layout Subsection
583 tdb_traverse Makes Impossible Guarantees
584 \end_layout
585
586 \begin_layout Standard
587 tdb_traverse (and tdb_firstkey/tdb_nextkey) predate transactions, and it
588  was thought that it was important to guarantee that all records which exist
589  at the start and end of the traversal would be included, and no record
590  would be included twice.
591 \end_layout
592
593 \begin_layout Standard
594 This adds complexity (see
595 \begin_inset CommandInset ref
596 LatexCommand ref
597 reference "Reliable-Traversal-Adds"
598
599 \end_inset
600
601 ) and does not work anyway for records which are altered (in particular,
602  those which are expanded may be effectively deleted and re-added behind
603  the traversal).
604 \end_layout
605
606 \begin_layout Subsubsection
607 \begin_inset CommandInset label
608 LatexCommand label
609 name "traverse-Proposed-Solution"
610
611 \end_inset
612
613 Proposed Solution
614 \end_layout
615
616 \begin_layout Standard
617 Abandon the guarantee.
618  You will see every record if no changes occur during your traversal, otherwise
619  you will see some subset.
620  You can prevent changes by using a transaction or the locking API.
621 \end_layout
622
623 \begin_layout Subsection
624 Nesting of Transactions Is Fraught
625 \end_layout
626
627 \begin_layout Standard
628 TDB has alternated between allowing nested transactions and not allowing
629  them.
630  Various paths in the Samba codebase assume that transactions will nest,
631  and in a sense they can: the operation is only committed to disk when the
632  outer transaction is committed.
633  There are two problems, however:
634 \end_layout
635
636 \begin_layout Enumerate
637 Canceling the inner transaction will cause the outer transaction commit
638  to fail, and will not undo any operations since the inner transaction began.
639  This problem is soluble with some additional internal code.
640 \end_layout
641
642 \begin_layout Enumerate
643 An inner transaction commit can be cancelled by the outer transaction.
644  This is desirable in the way which Samba's database initialization code
645  uses transactions, but could be a surprise to any users expecting a successful
646  transaction commit to expose changes to others.
647 \end_layout
648
649 \begin_layout Standard
650 The current solution is to specify the behavior at tdb_open(), with the
651  default currently that nested transactions are allowed.
652  This flag can also be changed at runtime.
653 \end_layout
654
655 \begin_layout Subsubsection
656 Proposed Solution
657 \end_layout
658
659 \begin_layout Standard
660 Given the usage patterns, it seems that the 
661 \begin_inset Quotes eld
662 \end_inset
663
664 least-surprise
665 \begin_inset Quotes erd
666 \end_inset
667
668  behavior of disallowing nested transactions should become the default.
669  Additionally, it seems the outer transaction is the only code which knows
670  whether inner transactions should be allowed, so a flag to indicate this
671  could be added to tdb_transaction_start.
672  However, this behavior can be simulated with a wrapper which uses tdb_add_flags
673 () and tdb_remove_flags(), so the API should not be expanded for this relatively
674 -obscure case.
675 \end_layout
676
677 \begin_layout Subsection
678 Incorrect Hash Function is Not Detected
679 \end_layout
680
681 \begin_layout Standard
682 tdb_open_ex() allows the calling code to specify a different hash function
683  to use, but does not check that all other processes accessing this tdb
684  are using the same hash function.
685  The result is that records are missing from tdb_fetch().
686 \end_layout
687
688 \begin_layout Subsubsection
689 Proposed Solution
690 \end_layout
691
692 \begin_layout Standard
693 The header should contain an example hash result (eg.
694  the hash of 0xdeadbeef), and tdb_open_ex() should check that the given
695  hash function produces the same answer, or fail the tdb_open call.
696 \end_layout
697
698 \begin_layout Subsection
699 tdb_set_max_dead/TDB_VOLATILE Expose Implementation
700 \end_layout
701
702 \begin_layout Standard
703 In response to scalability issues with the free list (
704 \begin_inset CommandInset ref
705 LatexCommand ref
706 reference "TDB-Freelist-Is"
707
708 \end_inset
709
710 ) two API workarounds have been incorporated in TDB: tdb_set_max_dead()
711  and the TDB_VOLATILE flag to tdb_open.
712  The latter actually calls the former with an argument of 
713 \begin_inset Quotes eld
714 \end_inset
715
716 5
717 \begin_inset Quotes erd
718 \end_inset
719
720 .
721 \end_layout
722
723 \begin_layout Standard
724 This code allows deleted records to accumulate without putting them in the
725  free list.
726  On delete we iterate through each chain and free them in a batch if there
727  are more than max_dead entries.
728  These are never otherwise recycled except as a side-effect of a tdb_repack.
729 \end_layout
730
731 \begin_layout Subsubsection
732 Proposed Solution
733 \end_layout
734
735 \begin_layout Standard
736 With the scalability problems of the freelist solved, this API can be removed.
737  The TDB_VOLATILE flag may still be useful as a hint that store and delete
738  of records will be at least as common as fetch in order to allow some internal
739  tuning, but initially will become a no-op.
740 \end_layout
741
742 \begin_layout Subsection
743 \begin_inset CommandInset label
744 LatexCommand label
745 name "TDB-Files-Cannot"
746
747 \end_inset
748
749 TDB Files Cannot Be Opened Multiple Times In The Same Process
750 \end_layout
751
752 \begin_layout Standard
753 No process can open the same TDB twice; we check and disallow it.
754  This is an unfortunate side-effect of fcntl locks, which operate on a per-file
755  rather than per-file-descriptor basis, and do not nest.
756  Thus, closing any file descriptor on a file clears all the locks obtained
757  by this process, even if they were placed using a different file descriptor!
758 \end_layout
759
760 \begin_layout Standard
761 Note that even if this were solved, deadlock could occur if operations were
762  nested: this is a more manageable programming error in most cases.
763 \end_layout
764
765 \begin_layout Subsubsection
766 Proposed Solution
767 \end_layout
768
769 \begin_layout Standard
770 We could lobby POSIX to fix the perverse rules, or at least lobby Linux
771  to violate them so that the most common implementation does not have this
772  restriction.
773  This would be a generally good idea for other fcntl lock users.
774 \end_layout
775
776 \begin_layout Standard
777 Samba uses a wrapper which hands out the same tdb_context to multiple callers
778  if this happens, and does simple reference counting.
779  We should do this inside the tdb library, which already emulates lock nesting
780  internally; it would need to recognize when deadlock occurs within a single
781  process.
782  This would create a new failure mode for tdb operations (while we currently
783  handle locking failures, they are impossible in normal use and a process
784  encountering them can do little but give up).
785 \end_layout
786
787 \begin_layout Standard
788 I do not see benefit in an additional tdb_open flag to indicate whether
789  re-opening is allowed, as though there may be some benefit to adding a
790  call to detect when a tdb_context is shared, to allow other to create such
791  an API.
792 \end_layout
793
794 \begin_layout Subsection
795 TDB API Is Not POSIX Thread-safe
796 \end_layout
797
798 \begin_layout Standard
799 The TDB API uses an error code which can be queried after an operation to
800  determine what went wrong.
801  This programming model does not work with threads, unless specific additional
802  guarantees are given by the implementation.
803  In addition, even otherwise-independent threads cannot open the same TDB
804  (as in 
805 \begin_inset CommandInset ref
806 LatexCommand ref
807 reference "TDB-Files-Cannot"
808
809 \end_inset
810
811 ).
812 \end_layout
813
814 \begin_layout Subsubsection
815 Proposed Solution
816 \end_layout
817
818 \begin_layout Standard
819 Reachitecting the API to include a tdb_errcode pointer would be a great
820  deal of churn; we are better to guarantee that the tdb_errcode is per-thread
821  so the current programming model can be maintained.
822 \end_layout
823
824 \begin_layout Standard
825 This requires dynamic per-thread allocations, which is awkward with POSIX
826  threads (pthread_key_create space is limited and we cannot simply allocate
827  a key for every TDB).
828 \end_layout
829
830 \begin_layout Standard
831 Internal locking is required to make sure that fcntl locks do not overlap
832  between threads, and also that the global list of tdbs is maintained.
833 \end_layout
834
835 \begin_layout Standard
836 The aim is that building tdb with -DTDB_PTHREAD will result in a pthread-safe
837  version of the library, and otherwise no overhead will exist.
838 \end_layout
839
840 \begin_layout Subsection
841 *_nonblock Functions And *_mark Functions Expose Implementation
842 \end_layout
843
844 \begin_layout Standard
845 CTDB
846 \begin_inset Foot
847 status collapsed
848
849 \begin_layout Plain Layout
850 Clustered TDB, see http://ctdb.samba.org
851 \end_layout
852
853 \end_inset
854
855  wishes to operate on TDB in a non-blocking manner.
856  This is currently done as follows:
857 \end_layout
858
859 \begin_layout Enumerate
860 Call the _nonblock variant of an API function (eg.
861  tdb_lockall_nonblock).
862  If this fails:
863 \end_layout
864
865 \begin_layout Enumerate
866 Fork a child process, and wait for it to call the normal variant (eg.
867  tdb_lockall).
868 \end_layout
869
870 \begin_layout Enumerate
871 If the child succeeds, call the _mark variant to indicate we already have
872  the locks (eg.
873  tdb_lockall_mark).
874 \end_layout
875
876 \begin_layout Enumerate
877 Upon completion, tell the child to release the locks (eg.
878  tdb_unlockall).
879 \end_layout
880
881 \begin_layout Enumerate
882 Indicate to tdb that it should consider the locks removed (eg.
883  tdb_unlockall_mark).
884 \end_layout
885
886 \begin_layout Standard
887 There are several issues with this approach.
888  Firstly, adding two new variants of each function clutters the API for
889  an obscure use, and so not all functions have three variants.
890  Secondly, it assumes that all paths of the functions ask for the same locks,
891  otherwise the parent process will have to get a lock which the child doesn't
892  have under some circumstances.
893  I don't believe this is currently the case, but it constrains the implementatio
894 n.
895  
896 \end_layout
897
898 \begin_layout Subsubsection
899 \begin_inset CommandInset label
900 LatexCommand label
901 name "Proposed-Solution-locking-hook"
902
903 \end_inset
904
905 Proposed Solution
906 \end_layout
907
908 \begin_layout Standard
909 Implement a hook for locking methods, so that the caller can control the
910  calls to create and remove fcntl locks.
911  In this scenario, ctdbd would operate as follows:
912 \end_layout
913
914 \begin_layout Enumerate
915 Call the normal API function, eg tdb_lockall().
916 \end_layout
917
918 \begin_layout Enumerate
919 When the lock callback comes in, check if the child has the lock.
920  Initially, this is always false.
921  If so, return 0.
922  Otherwise, try to obtain it in non-blocking mode.
923  If that fails, return EWOULDBLOCK.
924 \end_layout
925
926 \begin_layout Enumerate
927 Release locks in the unlock callback as normal.
928 \end_layout
929
930 \begin_layout Enumerate
931 If tdb_lockall() fails, see if we recorded a lock failure; if so, call the
932  child to repeat the operation.
933 \end_layout
934
935 \begin_layout Enumerate
936 The child records what locks it obtains, and returns that information to
937  the parent.
938 \end_layout
939
940 \begin_layout Enumerate
941 When the child has succeeded, goto 1.
942 \end_layout
943
944 \begin_layout Standard
945 This is flexible enough to handle any potential locking scenario, even when
946  lock requirements change.
947  It can be optimized so that the parent does not release locks, just tells
948  the child which locks it doesn't need to obtain.
949 \end_layout
950
951 \begin_layout Standard
952 It also keeps the complexity out of the API, and in ctdbd where it is needed.
953 \end_layout
954
955 \begin_layout Subsection
956 tdb_chainlock Functions Expose Implementation
957 \end_layout
958
959 \begin_layout Standard
960 tdb_chainlock locks some number of records, including the record indicated
961  by the given key.
962  This gave atomicity guarantees; no-one can start a transaction, alter,
963  read or delete that key while the lock is held.
964 \end_layout
965
966 \begin_layout Standard
967 It also makes the same guarantee for any other key in the chain, which is
968  an internal implementation detail and potentially a cause for deadlock.
969 \end_layout
970
971 \begin_layout Subsubsection
972 Proposed Solution
973 \end_layout
974
975 \begin_layout Standard
976 None.
977  It would be nice to have an explicit single entry lock which effected no
978  other keys.
979  Unfortunately, this won't work for an entry which doesn't exist.
980  Thus while chainlock may be implemented more efficiently for the existing
981  case, it will still have overlap issues with the non-existing case.
982  So it is best to keep the current (lack of) guarantee about which records
983  will be effected to avoid constraining our implementation.
984 \end_layout
985
986 \begin_layout Subsection
987 Signal Handling is Not Race-Free
988 \end_layout
989
990 \begin_layout Standard
991 The tdb_setalarm_sigptr() call allows the caller's signal handler to indicate
992  that the tdb locking code should return with a failure, rather than trying
993  again when a signal is received (and errno == EAGAIN).
994  This is usually used to implement timeouts.
995 \end_layout
996
997 \begin_layout Standard
998 Unfortunately, this does not work in the case where the signal is received
999  before the tdb code enters the fcntl() call to place the lock: the code
1000  will sleep within the fcntl() code, unaware that the signal wants it to
1001  exit.
1002  In the case of long timeouts, this does not happen in practice.
1003 \end_layout
1004
1005 \begin_layout Subsubsection
1006 Proposed Solution
1007 \end_layout
1008
1009 \begin_layout Standard
1010 The locking hooks proposed in
1011 \begin_inset CommandInset ref
1012 LatexCommand ref
1013 reference "Proposed-Solution-locking-hook"
1014
1015 \end_inset
1016
1017  would allow the user to decide on whether to fail the lock acquisition
1018  on a signal.
1019  This allows the caller to choose their own compromise: they could narrow
1020  the race by checking immediately before the fcntl call.
1021 \begin_inset Foot
1022 status collapsed
1023
1024 \begin_layout Plain Layout
1025 It may be possible to make this race-free in some implementations by having
1026  the signal handler alter the struct flock to make it invalid.
1027  This will cause the fcntl() lock call to fail with EINVAL if the signal
1028  occurs before the kernel is entered, otherwise EAGAIN.
1029 \end_layout
1030
1031 \end_inset
1032
1033
1034 \end_layout
1035
1036 \begin_layout Subsection
1037 The API Uses Gratuitous Typedefs, Capitals
1038 \end_layout
1039
1040 \begin_layout Standard
1041 typedefs are useful for providing source compatibility when types can differ
1042  across implementations, or arguably in the case of function pointer definitions
1043  which are hard for humans to parse.
1044  Otherwise it is simply obfuscation and pollutes the namespace.
1045 \end_layout
1046
1047 \begin_layout Standard
1048 Capitalization is usually reserved for compile-time constants and macros.
1049 \end_layout
1050
1051 \begin_layout Description
1052 TDB_CONTEXT There is no reason to use this over 'struct tdb_context'; the
1053  definition isn't visible to the API user anyway.
1054 \end_layout
1055
1056 \begin_layout Description
1057 TDB_DATA There is no reason to use this over struct TDB_DATA; the struct
1058  needs to be understood by the API user.
1059 \end_layout
1060
1061 \begin_layout Description
1062 struct
1063 \begin_inset space ~
1064 \end_inset
1065
1066 TDB_DATA This would normally be called 'struct tdb_data'.
1067 \end_layout
1068
1069 \begin_layout Description
1070 enum
1071 \begin_inset space ~
1072 \end_inset
1073
1074 TDB_ERROR Similarly, this would normally be enum tdb_error.
1075 \end_layout
1076
1077 \begin_layout Subsubsection
1078 Proposed Solution
1079 \end_layout
1080
1081 \begin_layout Standard
1082 None.
1083  Introducing lower case variants would please pedants like myself, but if
1084  it were done the existing ones should be kept.
1085  There is little point forcing a purely cosmetic change upon tdb users.
1086 \end_layout
1087
1088 \begin_layout Subsection
1089 \begin_inset CommandInset label
1090 LatexCommand label
1091 name "tdb_log_func-Doesnt-Take"
1092
1093 \end_inset
1094
1095 tdb_log_func Doesn't Take The Private Pointer
1096 \end_layout
1097
1098 \begin_layout Standard
1099 For API compatibility reasons, the logging function needs to call tdb_get_loggin
1100 g_private() to retrieve the pointer registered by the tdb_open_ex for logging.
1101 \end_layout
1102
1103 \begin_layout Subsubsection
1104 Proposed Solution
1105 \end_layout
1106
1107 \begin_layout Standard
1108 It should simply take an extra argument, since we are prepared to break
1109  the API/ABI.
1110 \end_layout
1111
1112 \begin_layout Subsection
1113 Various Callback Functions Are Not Typesafe
1114 \end_layout
1115
1116 \begin_layout Standard
1117 The callback functions in tdb_set_logging_function (after 
1118 \begin_inset CommandInset ref
1119 LatexCommand ref
1120 reference "tdb_log_func-Doesnt-Take"
1121
1122 \end_inset
1123
1124  is resolved), tdb_parse_record, tdb_traverse, tdb_traverse_read and tdb_check
1125  all take void * and must internally convert it to the argument type they
1126  were expecting.
1127 \end_layout
1128
1129 \begin_layout Standard
1130 If this type changes, the compiler will not produce warnings on the callers,
1131  since it only sees void *.
1132 \end_layout
1133
1134 \begin_layout Subsubsection
1135 Proposed Solution
1136 \end_layout
1137
1138 \begin_layout Standard
1139 With careful use of macros, we can create callback functions which give
1140  a warning when used on gcc and the types of the callback and its private
1141  argument differ.
1142  Unsupported compilers will not give a warning, which is no worse than now.
1143  In addition, the callbacks become clearer, as they need not use void *
1144  for their parameter.
1145 \end_layout
1146
1147 \begin_layout Standard
1148 See CCAN's typesafe_cb module at http://ccan.ozlabs.org/info/typesafe_cb.html
1149 \end_layout
1150
1151 \begin_layout Subsection
1152 TDB_CLEAR_IF_FIRST Must Be Specified On All Opens, tdb_reopen_all Problematic
1153 \end_layout
1154
1155 \begin_layout Standard
1156 The TDB_CLEAR_IF_FIRST flag to tdb_open indicates that the TDB file should
1157  be cleared if the caller discovers it is the only process with the TDB
1158  open.
1159  However, if any caller does not specify TDB_CLEAR_IF_FIRST it will not
1160  be detected, so will have the TDB erased underneath them (usually resulting
1161  in a crash).
1162 \end_layout
1163
1164 \begin_layout Standard
1165 There is a similar issue on fork(); if the parent exits (or otherwise closes
1166  the tdb) before the child calls tdb_reopen_all() to establish the lock
1167  used to indicate the TDB is opened by someone, a TDB_CLEAR_IF_FIRST opener
1168  at that moment will believe it alone has opened the TDB and will erase
1169  it.
1170 \end_layout
1171
1172 \begin_layout Subsubsection
1173 Proposed Solution
1174 \end_layout
1175
1176 \begin_layout Standard
1177 Remove TDB_CLEAR_IF_FIRST.
1178  Other workarounds are possible, but see 
1179 \begin_inset CommandInset ref
1180 LatexCommand ref
1181 reference "TDB_CLEAR_IF_FIRST-Imposes-Performance"
1182
1183 \end_inset
1184
1185 .
1186 \end_layout
1187
1188 \begin_layout Section
1189 Performance And Scalability Issues
1190 \end_layout
1191
1192 \begin_layout Subsection
1193 \begin_inset CommandInset label
1194 LatexCommand label
1195 name "TDB_CLEAR_IF_FIRST-Imposes-Performance"
1196
1197 \end_inset
1198
1199 TDB_CLEAR_IF_FIRST Imposes Performance Penalty
1200 \end_layout
1201
1202 \begin_layout Standard
1203 When TDB_CLEAR_IF_FIRST is specified, a 1-byte read lock is placed at offset
1204  4 (aka.
1205  the ACTIVE_LOCK).
1206  While these locks never conflict in normal tdb usage, they do add substantial
1207  overhead for most fcntl lock implementations when the kernel scans to detect
1208  if a lock conflict exists.
1209  This is often a single linked list, making the time to acquire and release
1210  a fcntl lock O(N) where N is the number of processes with the TDB open,
1211  not the number actually doing work.
1212 \end_layout
1213
1214 \begin_layout Standard
1215 In a Samba server it is common to have huge numbers of clients sitting idle,
1216  and thus they have weaned themselves off the TDB_CLEAR_IF_FIRST flag.
1217 \begin_inset Foot
1218 status collapsed
1219
1220 \begin_layout Plain Layout
1221 There is a flag to tdb_reopen_all() which is used for this optimization:
1222  if the parent process will outlive the child, the child does not need the
1223  ACTIVE_LOCK.
1224  This is a workaround for this very performance issue.
1225 \end_layout
1226
1227 \end_inset
1228
1229
1230 \end_layout
1231
1232 \begin_layout Subsubsection
1233 Proposed Solution
1234 \end_layout
1235
1236 \begin_layout Standard
1237 Remove the flag.
1238  It was a neat idea, but even trivial servers tend to know when they are
1239  initializing for the first time and can simply unlink the old tdb at that
1240  point.
1241 \end_layout
1242
1243 \begin_layout Subsection
1244 TDB Files Have a 4G Limit
1245 \end_layout
1246
1247 \begin_layout Standard
1248 This seems to be becoming an issue (so much for 
1249 \begin_inset Quotes eld
1250 \end_inset
1251
1252 trivial
1253 \begin_inset Quotes erd
1254 \end_inset
1255
1256 !), particularly for ldb.
1257 \end_layout
1258
1259 \begin_layout Subsubsection
1260 Proposed Solution
1261 \end_layout
1262
1263 \begin_layout Standard
1264 A new, incompatible TDB format which uses 64 bit offsets internally rather
1265  than 32 bit as now.
1266  For simplicity of endian conversion (which TDB does on the fly if required),
1267  all values will be 64 bit on disk.
1268  In practice, some upper bits may be used for other purposes, but at least
1269  56 bits will be available for file offsets.
1270 \end_layout
1271
1272 \begin_layout Standard
1273 tdb_open() will automatically detect the old version, and even create them
1274  if TDB_VERSION6 is specified to tdb_open.
1275 \end_layout
1276
1277 \begin_layout Standard
1278 32 bit processes will still be able to access TDBs larger than 4G (assuming
1279  that their off_t allows them to seek to 64 bits), they will gracefully
1280  fall back as they fail to mmap.
1281  This can happen already with large TDBs.
1282 \end_layout
1283
1284 \begin_layout Standard
1285 Old versions of tdb will fail to open the new TDB files (since 28 August
1286  2009, commit 398d0c29290: prior to that any unrecognized file format would
1287  be erased and initialized as a fresh tdb!)
1288 \end_layout
1289
1290 \begin_layout Subsection
1291 TDB Records Have a 4G Limit
1292 \end_layout
1293
1294 \begin_layout Standard
1295 This has not been a reported problem, and the API uses size_t which can
1296  be 64 bit on 64 bit platforms.
1297  However, other limits may have made such an issue moot.
1298 \end_layout
1299
1300 \begin_layout Subsubsection
1301 Proposed Solution
1302 \end_layout
1303
1304 \begin_layout Standard
1305 Record sizes will be 64 bit, with an error returned on 32 bit platforms
1306  which try to access such records (the current implementation would return
1307  TDB_ERR_OOM in a similar case).
1308  It seems unlikely that 32 bit keys will be a limitation, so the implementation
1309  may not support this (see 
1310 \begin_inset CommandInset ref
1311 LatexCommand ref
1312 reference "sub:Records-Incur-A"
1313
1314 \end_inset
1315
1316 ).
1317 \end_layout
1318
1319 \begin_layout Subsection
1320 Hash Size Is Determined At TDB Creation Time
1321 \end_layout
1322
1323 \begin_layout Standard
1324 TDB contains a number of hash chains in the header; the number is specified
1325  at creation time, and defaults to 131.
1326  This is such a bottleneck on large databases (as each hash chain gets quite
1327  long), that LDB uses 10,000 for this hash.
1328  In general it is impossible to know what the 'right' answer is at database
1329  creation time.
1330 \end_layout
1331
1332 \begin_layout Subsubsection
1333
1334 \change_inserted 0 1283336713
1335 \begin_inset CommandInset label
1336 LatexCommand label
1337 name "sub:Hash-Size-Solution"
1338
1339 \end_inset
1340
1341
1342 \change_unchanged
1343 Proposed Solution
1344 \end_layout
1345
1346 \begin_layout Standard
1347 After comprehensive performance testing on various scalable hash variants
1348 \begin_inset Foot
1349 status collapsed
1350
1351 \begin_layout Plain Layout
1352 http://rusty.ozlabs.org/?p=89 and http://rusty.ozlabs.org/?p=94 This was annoying
1353  because I was previously convinced that an expanding tree of hashes would
1354  be very close to optimal.
1355 \end_layout
1356
1357 \end_inset
1358
1359 , it became clear that it is hard to beat a straight linear hash table which
1360  doubles in size when it reaches saturation.
1361  
1362 \change_deleted 0 1283307675
1363 There are three details which become important:
1364 \end_layout
1365
1366 \begin_layout Enumerate
1367
1368 \change_deleted 0 1283307675
1369 On encountering a full bucket, we use the next bucket.
1370 \end_layout
1371
1372 \begin_layout Enumerate
1373
1374 \change_deleted 0 1283307675
1375 Extra hash bits are stored with the offset, to reduce comparisons.
1376 \end_layout
1377
1378 \begin_layout Enumerate
1379
1380 \change_deleted 0 1283307675
1381 A marker entry is used on deleting an entry.
1382 \end_layout
1383
1384 \begin_layout Standard
1385
1386 \change_deleted 0 1283307675
1387 The doubling of the table must be done under a transaction; we will not
1388  reduce it on deletion, so it will be an unusual case.
1389  It will either be placed at the head (other entries will be moved out the
1390  way so we can expand).
1391  We could have a pointer in the header to the current hashtable location,
1392  but that pointer would have to be read frequently to check for hashtable
1393  moves.
1394 \end_layout
1395
1396 \begin_layout Standard
1397
1398 \change_deleted 0 1283307675
1399 The locking for this is slightly more complex than the chained case; we
1400  currently have one lock per bucket, and that means we would need to expand
1401  the lock if we overflow to the next bucket.
1402  The frequency of such collisions will effect our locking heuristics: we
1403  can always lock more buckets than we need.
1404 \end_layout
1405
1406 \begin_layout Standard
1407
1408 \change_deleted 0 1283307675
1409 One possible optimization is to only re-check the hash size on an insert
1410  or a lookup miss.
1411
1412 \change_inserted 0 1283307770
1413  Unfortunately, altering the hash table introduces serious locking complications
1414 : the entire hash table needs to be locked to enlarge the hash table, and
1415  others might be holding locks.
1416  Particularly insidious are insertions done under tdb_chainlock.
1417 \end_layout
1418
1419 \begin_layout Standard
1420
1421 \change_inserted 0 1283336187
1422 Thus an expanding layered hash will be used: an array of hash groups, with
1423  each hash group exploding into pointers to lower hash groups once it fills,
1424  turning into a hash tree.
1425  This has implications for locking: we must lock the entire group in case
1426  we need to expand it, yet we don't know how deep the tree is at that point.
1427 \end_layout
1428
1429 \begin_layout Standard
1430
1431 \change_inserted 0 1283336586
1432 Note that bits from the hash table entries should be stolen to hold more
1433  hash bits to reduce the penalty of collisions.
1434  We can use the otherwise-unused lower 3 bits.
1435  If we limit the size of the database to 64 exabytes, we can use the top
1436  8 bits of the hash entry as well.
1437  These 11 bits would reduce false positives down to 1 in 2000 which is more
1438  than we need: we can use one of the bits to indicate that the extra hash
1439  bits are valid.
1440  This means we can choose not to re-hash all entries when we expand a hash
1441  group; simply use the next bits we need and mark them invalid.
1442 \change_unchanged
1443
1444 \end_layout
1445
1446 \begin_layout Subsection
1447 \begin_inset CommandInset label
1448 LatexCommand label
1449 name "TDB-Freelist-Is"
1450
1451 \end_inset
1452
1453 TDB Freelist Is Highly Contended
1454 \end_layout
1455
1456 \begin_layout Standard
1457 TDB uses a single linked list for the free list.
1458  Allocation occurs as follows, using heuristics which have evolved over
1459  time:
1460 \end_layout
1461
1462 \begin_layout Enumerate
1463 Get the free list lock for this whole operation.
1464 \end_layout
1465
1466 \begin_layout Enumerate
1467 Multiply length by 1.25, so we always over-allocate by 25%.
1468 \end_layout
1469
1470 \begin_layout Enumerate
1471 Set the slack multiplier to 1.
1472 \end_layout
1473
1474 \begin_layout Enumerate
1475 Examine the current freelist entry: if it is > length but < the current
1476  best case, remember it as the best case.
1477 \end_layout
1478
1479 \begin_layout Enumerate
1480 Multiply the slack multiplier by 1.05.
1481 \end_layout
1482
1483 \begin_layout Enumerate
1484 If our best fit so far is less than length * slack multiplier, return it.
1485  The slack will be turned into a new free record if it's large enough.
1486 \end_layout
1487
1488 \begin_layout Enumerate
1489 Otherwise, go onto the next freelist entry.
1490 \end_layout
1491
1492 \begin_layout Standard
1493 Deleting a record occurs as follows:
1494 \end_layout
1495
1496 \begin_layout Enumerate
1497 Lock the hash chain for this whole operation.
1498 \end_layout
1499
1500 \begin_layout Enumerate
1501 Walk the chain to find the record, keeping the prev pointer offset.
1502 \end_layout
1503
1504 \begin_layout Enumerate
1505 If max_dead is non-zero:
1506 \end_layout
1507
1508 \begin_deeper
1509 \begin_layout Enumerate
1510 Walk the hash chain again and count the dead records.
1511 \end_layout
1512
1513 \begin_layout Enumerate
1514 If it's more than max_dead, bulk free all the dead ones (similar to steps
1515  4 and below, but the lock is only obtained once).
1516 \end_layout
1517
1518 \begin_layout Enumerate
1519 Simply mark this record as dead and return.
1520  
1521 \end_layout
1522
1523 \end_deeper
1524 \begin_layout Enumerate
1525 Get the free list lock for the remainder of this operation.
1526 \end_layout
1527
1528 \begin_layout Enumerate
1529 \begin_inset CommandInset label
1530 LatexCommand label
1531 name "right-merging"
1532
1533 \end_inset
1534
1535 Examine the following block to see if it is free; if so, enlarge the current
1536  block and remove that block from the free list.
1537  This was disabled, as removal from the free list was O(entries-in-free-list).
1538 \end_layout
1539
1540 \begin_layout Enumerate
1541 Examine the preceeding block to see if it is free: for this reason, each
1542  block has a 32-bit tailer which indicates its length.
1543  If it is free, expand it to cover our new block and return.
1544 \end_layout
1545
1546 \begin_layout Enumerate
1547 Otherwise, prepend ourselves to the free list.
1548 \end_layout
1549
1550 \begin_layout Standard
1551 Disabling right-merging (step 
1552 \begin_inset CommandInset ref
1553 LatexCommand ref
1554 reference "right-merging"
1555
1556 \end_inset
1557
1558 ) causes fragmentation; the other heuristics proved insufficient to address
1559  this, so the final answer to this was that when we expand the TDB file
1560  inside a transaction commit, we repack the entire tdb.
1561 \end_layout
1562
1563 \begin_layout Standard
1564 The single list lock limits our allocation rate; due to the other issues
1565  this is not currently seen as a bottleneck.
1566 \end_layout
1567
1568 \begin_layout Subsubsection
1569 Proposed Solution
1570 \change_deleted 0 1283336858
1571
1572 \end_layout
1573
1574 \begin_layout Standard
1575 The first step is to remove all the current heuristics, as they obviously
1576  interact, then examine them once the lock contention is addressed.
1577 \end_layout
1578
1579 \begin_layout Standard
1580 The free list must be split to reduce contention.
1581  Assuming perfect free merging, we can at most have 1 free list entry for
1582  each entry.
1583  This implies that the number of free lists is related to the size of the
1584  hash table, but as it is rare to walk a large number of free list entries
1585  we can use far fewer, say 1/32 of the number of hash buckets.
1586 \change_inserted 0 1283336910
1587
1588 \end_layout
1589
1590 \begin_layout Standard
1591
1592 \change_inserted 0 1283337052
1593 It seems tempting to try to reuse the hash implementation which we use for
1594  records here, but we have two ways of searching for free entries: for allocatio
1595 n we search by size (and possibly zone) which produces too many clashes
1596  for our hash table to handle well, and for coalescing we search by address.
1597  Thus an array of doubly-linked free lists seems preferable.
1598 \change_unchanged
1599
1600 \end_layout
1601
1602 \begin_layout Standard
1603 There are various benefits in using per-size free lists (see 
1604 \begin_inset CommandInset ref
1605 LatexCommand ref
1606 reference "sub:TDB-Becomes-Fragmented"
1607
1608 \end_inset
1609
1610 ) but it's not clear this would reduce contention in the common case where
1611  all processes are allocating/freeing the same size.
1612  Thus we almost certainly need to divide in other ways: the most obvious
1613  is to divide the file into zones, and using a free list (or set of free
1614  lists) for each.
1615  This approximates address ordering.
1616 \end_layout
1617
1618 \begin_layout Standard
1619 Note that this means we need to split the free lists when we expand the
1620  file; this is probably acceptable when we double the hash table size, since
1621  that is such an expensive operation already.
1622  In the case of increasing the file size, there is an optimization we can
1623  use: if we use M in the formula above as the file size rounded up to the
1624  next power of 2, we only need reshuffle free lists when the file size crosses
1625  a power of 2 boundary, 
1626 \emph on
1627 and 
1628 \emph default
1629 reshuffling the free lists is trivial: we simply merge every consecutive
1630  pair of free lists.
1631 \end_layout
1632
1633 \begin_layout Standard
1634 The basic algorithm is as follows.
1635  Freeing is simple:
1636 \end_layout
1637
1638 \begin_layout Enumerate
1639 Identify the correct zone.
1640 \end_layout
1641
1642 \begin_layout Enumerate
1643 Lock the corresponding list.
1644 \end_layout
1645
1646 \begin_layout Enumerate
1647 Re-check the zone (we didn't have a lock, sizes could have changed): relock
1648  if necessary.
1649 \end_layout
1650
1651 \begin_layout Enumerate
1652 Place the freed entry in the list for that zone.
1653 \end_layout
1654
1655 \begin_layout Standard
1656 Allocation is a little more complicated, as we perform delayed coalescing
1657  at this point:
1658 \end_layout
1659
1660 \begin_layout Enumerate
1661 Pick a zone either the zone we last freed into, or based on a 
1662 \begin_inset Quotes eld
1663 \end_inset
1664
1665 random
1666 \begin_inset Quotes erd
1667 \end_inset
1668
1669  number.
1670 \end_layout
1671
1672 \begin_layout Enumerate
1673 Lock the corresponding list.
1674 \end_layout
1675
1676 \begin_layout Enumerate
1677 Re-check the zone: relock if necessary.
1678 \end_layout
1679
1680 \begin_layout Enumerate
1681 If the top entry is -large enough, remove it from the list and return it.
1682 \end_layout
1683
1684 \begin_layout Enumerate
1685 Otherwise, coalesce entries in the list.If there was no entry large enough,
1686  unlock the list and try the next zone.
1687 \end_layout
1688
1689 \begin_layout Enumerate
1690 If no zone satisfies, expand the file.
1691 \end_layout
1692
1693 \begin_layout Standard
1694 This optimizes rapid insert/delete of free list entries by not coalescing
1695  them all the time..
1696  First-fit address ordering ordering seems to be fairly good for keeping
1697  fragmentation low (see 
1698 \begin_inset CommandInset ref
1699 LatexCommand ref
1700 reference "sub:TDB-Becomes-Fragmented"
1701
1702 \end_inset
1703
1704 ).
1705  Note that address ordering does not need a tailer to coalesce, though if
1706  we needed one we could have one cheaply: see 
1707 \begin_inset CommandInset ref
1708 LatexCommand ref
1709 reference "sub:Records-Incur-A"
1710
1711 \end_inset
1712
1713 .
1714  
1715 \end_layout
1716
1717 \begin_layout Standard
1718 I anticipate that the number of entries in each free zone would be small,
1719  but it might be worth using one free entry to hold pointers to the others
1720  for cache efficiency.
1721 \change_inserted 0 1283309850
1722
1723 \end_layout
1724
1725 \begin_layout Standard
1726
1727 \change_inserted 0 1283337216
1728 \begin_inset CommandInset label
1729 LatexCommand label
1730 name "freelist-in-zone"
1731
1732 \end_inset
1733
1734 If we want to avoid locking complexity (enlarging the free lists when we
1735  enlarge the file) we could place the array of free lists at the beginning
1736  of each zone.
1737  This means existing array lists never move, but means that a record cannot
1738  be larger than a zone.
1739  That in turn implies that zones should be variable sized (say, power of
1740  2), which makes the question 
1741 \begin_inset Quotes eld
1742 \end_inset
1743
1744 what zone is this record in?
1745 \begin_inset Quotes erd
1746 \end_inset
1747
1748  much harder (and 
1749 \begin_inset Quotes eld
1750 \end_inset
1751
1752 pick a random zone
1753 \begin_inset Quotes erd
1754 \end_inset
1755
1756 , but that's less common).
1757  It could be done with as few as 4 bits from the record header.
1758 \begin_inset Foot
1759 status open
1760
1761 \begin_layout Plain Layout
1762
1763 \change_inserted 0 1283310945
1764 Using 
1765 \begin_inset Formula $2^{16+N*3}$
1766 \end_inset
1767
1768 means 0 gives a minimal 65536-byte zone, 15 gives the maximal 
1769 \begin_inset Formula $2^{61}$
1770 \end_inset
1771
1772  byte zone.
1773  Zones range in factor of 8 steps.
1774 \change_unchanged
1775
1776 \end_layout
1777
1778 \end_inset
1779
1780
1781 \change_unchanged
1782
1783 \end_layout
1784
1785 \begin_layout Subsection
1786 \begin_inset CommandInset label
1787 LatexCommand label
1788 name "sub:TDB-Becomes-Fragmented"
1789
1790 \end_inset
1791
1792 TDB Becomes Fragmented
1793 \end_layout
1794
1795 \begin_layout Standard
1796 Much of this is a result of allocation strategy
1797 \begin_inset Foot
1798 status collapsed
1799
1800 \begin_layout Plain Layout
1801 The Memory Fragmentation Problem: Solved? Johnstone & Wilson 1995 ftp://ftp.cs.ute
1802 xas.edu/pub/garbage/malloc/ismm98.ps
1803 \end_layout
1804
1805 \end_inset
1806
1807  and deliberate hobbling of coalescing; internal fragmentation (aka overallocati
1808 on) is deliberately set at 25%, and external fragmentation is only cured
1809  by the decision to repack the entire db when a transaction commit needs
1810  to enlarge the file.
1811 \end_layout
1812
1813 \begin_layout Subsubsection
1814 Proposed Solution
1815 \end_layout
1816
1817 \begin_layout Standard
1818 The 25% overhead on allocation works in practice for ldb because indexes
1819  tend to expand by one record at a time.
1820  This internal fragmentation can be resolved by having an 
1821 \begin_inset Quotes eld
1822 \end_inset
1823
1824 expanded
1825 \begin_inset Quotes erd
1826 \end_inset
1827
1828  bit in the header to note entries that have previously expanded, and allocating
1829  more space for them.
1830 \end_layout
1831
1832 \begin_layout Standard
1833 There are is a spectrum of possible solutions for external fragmentation:
1834  one is to use a fragmentation-avoiding allocation strategy such as best-fit
1835  address-order allocator.
1836  The other end of the spectrum would be to use a bump allocator (very fast
1837  and simple) and simply repack the file when we reach the end.
1838 \end_layout
1839
1840 \begin_layout Standard
1841 There are three problems with efficient fragmentation-avoiding allocators:
1842  they are non-trivial, they tend to use a single free list for each size,
1843  and there's no evidence that tdb allocation patterns will match those recorded
1844  for general allocators (though it seems likely).
1845 \end_layout
1846
1847 \begin_layout Standard
1848 Thus we don't spend too much effort on external fragmentation; we will be
1849  no worse than the current code if we need to repack on occasion.
1850  More effort is spent on reducing freelist contention, and reducing overhead.
1851 \end_layout
1852
1853 \begin_layout Subsection
1854 \begin_inset CommandInset label
1855 LatexCommand label
1856 name "sub:Records-Incur-A"
1857
1858 \end_inset
1859
1860 Records Incur A 28-Byte Overhead
1861 \end_layout
1862
1863 \begin_layout Standard
1864 Each TDB record has a header as follows:
1865 \end_layout
1866
1867 \begin_layout LyX-Code
1868 struct tdb_record {
1869 \end_layout
1870
1871 \begin_layout LyX-Code
1872         tdb_off_t next; /* offset of the next record in the list */
1873 \end_layout
1874
1875 \begin_layout LyX-Code
1876         tdb_len_t rec_len; /* total byte length of record */
1877 \end_layout
1878
1879 \begin_layout LyX-Code
1880         tdb_len_t key_len; /* byte length of key */
1881 \end_layout
1882
1883 \begin_layout LyX-Code
1884         tdb_len_t data_len; /* byte length of data */
1885 \end_layout
1886
1887 \begin_layout LyX-Code
1888         uint32_t full_hash; /* the full 32 bit hash of the key */
1889 \end_layout
1890
1891 \begin_layout LyX-Code
1892         uint32_t magic;   /* try to catch errors */
1893 \end_layout
1894
1895 \begin_layout LyX-Code
1896         /* the following union is implied:
1897 \end_layout
1898
1899 \begin_layout LyX-Code
1900                 union {
1901 \end_layout
1902
1903 \begin_layout LyX-Code
1904                         char record[rec_len];
1905 \end_layout
1906
1907 \begin_layout LyX-Code
1908                         struct {
1909 \end_layout
1910
1911 \begin_layout LyX-Code
1912                                 char key[key_len];
1913 \end_layout
1914
1915 \begin_layout LyX-Code
1916                                 char data[data_len];
1917 \end_layout
1918
1919 \begin_layout LyX-Code
1920                         }
1921 \end_layout
1922
1923 \begin_layout LyX-Code
1924                         uint32_t totalsize; (tailer)
1925 \end_layout
1926
1927 \begin_layout LyX-Code
1928                 }
1929 \end_layout
1930
1931 \begin_layout LyX-Code
1932         */
1933 \end_layout
1934
1935 \begin_layout LyX-Code
1936 };
1937 \end_layout
1938
1939 \begin_layout Standard
1940 Naively, this would double to a 56-byte overhead on a 64 bit implementation.
1941 \end_layout
1942
1943 \begin_layout Subsubsection
1944 Proposed Solution
1945 \end_layout
1946
1947 \begin_layout Standard
1948 We can use various techniques to reduce this for an allocated block:
1949 \end_layout
1950
1951 \begin_layout Enumerate
1952 The 'next' pointer is not required, as we are using a flat hash table.
1953 \end_layout
1954
1955 \begin_layout Enumerate
1956 'rec_len' can instead be expressed as an addition to key_len and data_len
1957  (it accounts for wasted or overallocated length in the record).
1958  Since the record length is always a multiple of 8, we can conveniently
1959  fit it in 32 bits (representing up to 35 bits).
1960 \end_layout
1961
1962 \begin_layout Enumerate
1963 'key_len' and 'data_len' can be reduced.
1964  I'm unwilling to restrict 'data_len' to 32 bits, but instead we can combine
1965  the two into one 64-bit field and using a 5 bit value which indicates at
1966  what bit to divide the two.
1967  Keys are unlikely to scale as fast as data, so I'm assuming a maximum key
1968  size of 32 bits.
1969 \end_layout
1970
1971 \begin_layout Enumerate
1972 'full_hash' is used to avoid a memcmp on the 
1973 \begin_inset Quotes eld
1974 \end_inset
1975
1976 miss
1977 \begin_inset Quotes erd
1978 \end_inset
1979
1980  case, but this is diminishing returns after a handful of bits (at 10 bits,
1981  it reduces 99.9% of false memcmp).
1982  As an aside, as the lower bits are already incorporated in the hash table
1983  resolution, the upper bits should be used here.
1984
1985 \change_inserted 0 1283336739
1986  Note that it's not clear that these bits will be a win, given the extra
1987  bits in the hash table itself (see 
1988 \begin_inset CommandInset ref
1989 LatexCommand ref
1990 reference "sub:Hash-Size-Solution"
1991
1992 \end_inset
1993
1994 ).
1995 \change_unchanged
1996
1997 \end_layout
1998
1999 \begin_layout Enumerate
2000 'magic' does not need to be enlarged: it currently reflects one of 5 values
2001  (used, free, dead, recovery, and unused_recovery).
2002  It is useful for quick sanity checking however, and should not be eliminated.
2003 \end_layout
2004
2005 \begin_layout Enumerate
2006 'tailer' is only used to coalesce free blocks (so a block to the right can
2007  find the header to check if this block is free).
2008  This can be replaced by a single 'free' bit in the header of the following
2009  block (and the tailer only exists in free blocks).
2010 \begin_inset Foot
2011 status collapsed
2012
2013 \begin_layout Plain Layout
2014 This technique from Thomas Standish.
2015  Data Structure Techniques.
2016  Addison-Wesley, Reading, Massachusetts, 1980.
2017 \end_layout
2018
2019 \end_inset
2020
2021  The current proposed coalescing algorithm doesn't need this, however.
2022 \end_layout
2023
2024 \begin_layout Standard
2025 This produces a 16 byte used header like this:
2026 \end_layout
2027
2028 \begin_layout LyX-Code
2029 struct tdb_used_record {
2030 \end_layout
2031
2032 \begin_layout LyX-Code
2033         uint32_t magic : 16,
2034 \end_layout
2035
2036 \begin_layout LyX-Code
2037                  prev_is_free: 1,
2038 \end_layout
2039
2040 \begin_layout LyX-Code
2041                  key_data_divide: 5,
2042 \end_layout
2043
2044 \begin_layout LyX-Code
2045                  top_hash: 10;
2046 \end_layout
2047
2048 \begin_layout LyX-Code
2049         uint32_t extra_octets;
2050 \end_layout
2051
2052 \begin_layout LyX-Code
2053         uint64_t key_and_data_len;
2054 \end_layout
2055
2056 \begin_layout LyX-Code
2057 };
2058 \end_layout
2059
2060 \begin_layout Standard
2061 And a free record like this:
2062 \end_layout
2063
2064 \begin_layout LyX-Code
2065 struct tdb_free_record {
2066 \end_layout
2067
2068 \begin_layout LyX-Code
2069         uint32_t free_magic;
2070 \end_layout
2071
2072 \begin_layout LyX-Code
2073         uint64_t total_length;
2074 \change_inserted 0 1283337133
2075
2076 \end_layout
2077
2078 \begin_layout LyX-Code
2079
2080 \change_inserted 0 1283337139
2081         uint64_t prev, next;
2082 \change_unchanged
2083
2084 \end_layout
2085
2086 \begin_layout LyX-Code
2087         ...
2088 \end_layout
2089
2090 \begin_layout LyX-Code
2091         uint64_t tailer;
2092 \end_layout
2093
2094 \begin_layout LyX-Code
2095 };
2096 \end_layout
2097
2098 \begin_layout Standard
2099
2100 \change_inserted 0 1283337235
2101 We might want to take some bits from the used record's top_hash (and the
2102  free record which has 32 bits of padding to spare anyway) if we use variable
2103  sized zones.
2104  See 
2105 \begin_inset CommandInset ref
2106 LatexCommand ref
2107 reference "freelist-in-zone"
2108
2109 \end_inset
2110
2111 .
2112 \change_unchanged
2113
2114 \end_layout
2115
2116 \begin_layout Subsection
2117 Transaction Commit Requires 4 fdatasync
2118 \end_layout
2119
2120 \begin_layout Standard
2121 The current transaction algorithm is:
2122 \end_layout
2123
2124 \begin_layout Enumerate
2125 write_recovery_data();
2126 \end_layout
2127
2128 \begin_layout Enumerate
2129 sync();
2130 \end_layout
2131
2132 \begin_layout Enumerate
2133 write_recovery_header();
2134 \end_layout
2135
2136 \begin_layout Enumerate
2137 sync();
2138 \end_layout
2139
2140 \begin_layout Enumerate
2141 overwrite_with_new_data();
2142 \end_layout
2143
2144 \begin_layout Enumerate
2145 sync();
2146 \end_layout
2147
2148 \begin_layout Enumerate
2149 remove_recovery_header();
2150 \end_layout
2151
2152 \begin_layout Enumerate
2153 sync(); 
2154 \end_layout
2155
2156 \begin_layout Standard
2157 On current ext3, each sync flushes all data to disk, so the next 3 syncs
2158  are relatively expensive.
2159  But this could become a performance bottleneck on other filesystems such
2160  as ext4.
2161 \end_layout
2162
2163 \begin_layout Subsubsection
2164 Proposed Solution
2165 \end_layout
2166
2167 \begin_layout Standard
2168 Neil Brown points out that this is overzealous, and only one sync is needed:
2169 \end_layout
2170
2171 \begin_layout Enumerate
2172 Bundle the recovery data, a transaction counter and a strong checksum of
2173  the new data.
2174 \end_layout
2175
2176 \begin_layout Enumerate
2177 Strong checksum that whole bundle.
2178 \end_layout
2179
2180 \begin_layout Enumerate
2181 Store the bundle in the database.
2182 \end_layout
2183
2184 \begin_layout Enumerate
2185 Overwrite the oldest of the two recovery pointers in the header (identified
2186  using the transaction counter) with the offset of this bundle.
2187 \end_layout
2188
2189 \begin_layout Enumerate
2190 sync.
2191 \end_layout
2192
2193 \begin_layout Enumerate
2194 Write the new data to the file.
2195 \end_layout
2196
2197 \begin_layout Standard
2198 Checking for recovery means identifying the latest bundle with a valid checksum
2199  and using the new data checksum to ensure that it has been applied.
2200  This is more expensive than the current check, but need only be done at
2201  open.
2202  For running databases, a separate header field can be used to indicate
2203  a transaction in progress; we need only check for recovery if this is set.
2204 \end_layout
2205
2206 \begin_layout Subsection
2207 \begin_inset CommandInset label
2208 LatexCommand label
2209 name "sub:TDB-Does-Not"
2210
2211 \end_inset
2212
2213 TDB Does Not Have Snapshot Support
2214 \end_layout
2215
2216 \begin_layout Subsubsection
2217 Proposed Solution
2218 \end_layout
2219
2220 \begin_layout Standard
2221 None.
2222  At some point you say 
2223 \begin_inset Quotes eld
2224 \end_inset
2225
2226 use a real database
2227 \begin_inset Quotes erd
2228 \end_inset
2229
2230 .
2231 \end_layout
2232
2233 \begin_layout Standard
2234 But as a thought experiment, if we implemented transactions to only overwrite
2235  free entries (this is tricky: there must not be a header in each entry
2236  which indicates whether it is free, but use of presence in metadata elsewhere),
2237  and a pointer to the hash table, we could create an entirely new commit
2238  without destroying existing data.
2239  Then it would be easy to implement snapshots in a similar way.
2240 \end_layout
2241
2242 \begin_layout Standard
2243 This would not allow arbitrary changes to the database, such as tdb_repack
2244  does, and would require more space (since we have to preserve the current
2245  and future entries at once).
2246  If we used hash trees rather than one big hash table, we might only have
2247  to rewrite some sections of the hash, too.
2248 \end_layout
2249
2250 \begin_layout Standard
2251 We could then implement snapshots using a similar method, using multiple
2252  different hash tables/free tables.
2253 \end_layout
2254
2255 \begin_layout Subsection
2256 Transactions Cannot Operate in Parallel
2257 \end_layout
2258
2259 \begin_layout Standard
2260 This would be useless for ldb, as it hits the index records with just about
2261  every update.
2262  It would add significant complexity in resolving clashes, and cause the
2263  all transaction callers to write their code to loop in the case where the
2264  transactions spuriously failed.
2265 \end_layout
2266
2267 \begin_layout Subsubsection
2268 Proposed Solution
2269 \end_layout
2270
2271 \begin_layout Standard
2272 We could solve a small part of the problem by providing read-only transactions.
2273  These would allow one write transaction to begin, but it could not commit
2274  until all r/o transactions are done.
2275  This would require a new RO_TRANSACTION_LOCK, which would be upgraded on
2276  commit.
2277 \end_layout
2278
2279 \begin_layout Subsection
2280 Default Hash Function Is Suboptimal
2281 \end_layout
2282
2283 \begin_layout Standard
2284 The Knuth-inspired multiplicative hash used by tdb is fairly slow (especially
2285  if we expand it to 64 bits), and works best when the hash bucket size is
2286  a prime number (which also means a slow modulus).
2287  In addition, it is highly predictable which could potentially lead to a
2288  Denial of Service attack in some TDB uses.
2289 \end_layout
2290
2291 \begin_layout Subsubsection
2292 Proposed Solution
2293 \end_layout
2294
2295 \begin_layout Standard
2296 The Jenkins lookup3 hash
2297 \begin_inset Foot
2298 status open
2299
2300 \begin_layout Plain Layout
2301 http://burtleburtle.net/bob/c/lookup3.c
2302 \end_layout
2303
2304 \end_inset
2305
2306  is a fast and superbly-mixing hash.
2307  It's used by the Linux kernel and almost everything else.
2308  This has the particular properties that it takes an initial seed, and produces
2309  two 32 bit hash numbers, which we can combine into a 64-bit hash.
2310 \end_layout
2311
2312 \begin_layout Standard
2313 The seed should be created at tdb-creation time from some random source,
2314  and placed in the header.
2315  This is far from foolproof, but adds a little bit of protection against
2316  hash bombing.
2317 \end_layout
2318
2319 \begin_layout Subsection
2320 \begin_inset CommandInset label
2321 LatexCommand label
2322 name "Reliable-Traversal-Adds"
2323
2324 \end_inset
2325
2326 Reliable Traversal Adds Complexity
2327 \end_layout
2328
2329 \begin_layout Standard
2330 We lock a record during traversal iteration, and try to grab that lock in
2331  the delete code.
2332  If that grab on delete fails, we simply mark it deleted and continue onwards;
2333  traversal checks for this condition and does the delete when it moves off
2334  the record.
2335 \end_layout
2336
2337 \begin_layout Standard
2338 If traversal terminates, the dead record may be left indefinitely.
2339 \end_layout
2340
2341 \begin_layout Subsubsection
2342 Proposed Solution
2343 \end_layout
2344
2345 \begin_layout Standard
2346 Remove reliability guarantees; see 
2347 \begin_inset CommandInset ref
2348 LatexCommand ref
2349 reference "traverse-Proposed-Solution"
2350
2351 \end_inset
2352
2353 .
2354 \end_layout
2355
2356 \begin_layout Subsection
2357 Fcntl Locking Adds Overhead
2358 \end_layout
2359
2360 \begin_layout Standard
2361 Placing a fcntl lock means a system call, as does removing one.
2362  This is actually one reason why transactions can be faster (everything
2363  is locked once at transaction start).
2364  In the uncontended case, this overhead can theoretically be eliminated.
2365 \end_layout
2366
2367 \begin_layout Subsubsection
2368 Proposed Solution
2369 \end_layout
2370
2371 \begin_layout Standard
2372 None.
2373 \end_layout
2374
2375 \begin_layout Standard
2376 We tried this before with spinlock support, in the early days of TDB, and
2377  it didn't make much difference except in manufactured benchmarks.
2378 \end_layout
2379
2380 \begin_layout Standard
2381 We could use spinlocks (with futex kernel support under Linux), but it means
2382  that we lose automatic cleanup when a process dies with a lock.
2383  There is a method of auto-cleanup under Linux, but it's not supported by
2384  other operating systems.
2385  We could reintroduce a clear-if-first-style lock and sweep for dead futexes
2386  on open, but that wouldn't help the normal case of one concurrent opener
2387  dying.
2388  Increasingly elaborate repair schemes could be considered, but they require
2389  an ABI change (everyone must use them) anyway, so there's no need to do
2390  this at the same time as everything else.
2391 \end_layout
2392
2393 \begin_layout Subsection
2394 Some Transactions Don't Require Durability
2395 \end_layout
2396
2397 \begin_layout Standard
2398 Volker points out that gencache uses a CLEAR_IF_FIRST tdb for normal (fast)
2399  usage, and occasionally empties the results into a transactional TDB.
2400  This kind of usage prioritizes performance over durability: as long as
2401  we are consistent, data can be lost.
2402 \end_layout
2403
2404 \begin_layout Standard
2405 This would be more neatly implemented inside tdb: a 
2406 \begin_inset Quotes eld
2407 \end_inset
2408
2409 soft
2410 \begin_inset Quotes erd
2411 \end_inset
2412
2413  transaction commit (ie.
2414  syncless) which meant that data may be reverted on a crash.
2415 \end_layout
2416
2417 \begin_layout Subsubsection
2418 Proposed Solution
2419 \end_layout
2420
2421 \begin_layout Standard
2422 None.
2423 \end_layout
2424
2425 \begin_layout Standard
2426 Unfortunately any transaction scheme which overwrites old data requires
2427  a sync before that overwrite to avoid the possibility of corruption.
2428 \end_layout
2429
2430 \begin_layout Standard
2431 It seems possible to use a scheme similar to that described in 
2432 \begin_inset CommandInset ref
2433 LatexCommand ref
2434 reference "sub:TDB-Does-Not"
2435
2436 \end_inset
2437
2438 ,where transactions are committed without overwriting existing data, and
2439  an array of top-level pointers were available in the header.
2440  If the transaction is 
2441 \begin_inset Quotes eld
2442 \end_inset
2443
2444 soft
2445 \begin_inset Quotes erd
2446 \end_inset
2447
2448  then we would not need a sync at all: existing processes would pick up
2449  the new hash table and free list and work with that.
2450 \end_layout
2451
2452 \begin_layout Standard
2453 At some later point, a sync would allow recovery of the old data into the
2454  free lists (perhaps when the array of top-level pointers filled).
2455  On crash, tdb_open() would examine the array of top levels, and apply the
2456  transactions until it encountered an invalid checksum.
2457 \end_layout
2458
2459 \end_body
2460 \end_document