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