1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-25 06:04:04 +03:00

34 Commits

Author SHA1 Message Date
Volker Lendecke
5a388453e0 tdb: Introduce tdb_oob()
Initially just encapsulate the pointer dereferences

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
2019-08-06 21:49:27 +00:00
Volker Lendecke
8d787f73bb tdb: Align integer types
tdb->max_dead_records is "int", as is the corresponding parameter to
tdb_set_max_dead(). Not that a signed variable makes any sense, but
this is old code and tdb_set_max_dead() is a public API which we
should not change for this.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>

Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Tue Nov  6 21:52:32 CET 2018 on sn-devel-144
2018-11-06 21:52:32 +01:00
Volker Lendecke
500a729a55 tdb: Make record deletion circular-chain safe
Before this patch we had 3 loops walking a hash chain to delete
records:

tdb_do_delete() to find the predecessor of the record that was to be
deleted. tdb_count_dead(), the name says it all and tdb_purge_dead()
to give back all dead records from a chain to the freelist.

This patch introduces tdb_trim_dead that walks a hash chain just
once. While it does so it counts the number of dead records, and all
records beyond tdb->max_dead_records are moved to the freelist.

Normal record deletion now works by always marking a record as dead in
step 1 and then calling tdb_trim_dead. This is made safe against
circular chains by doing the slow chain walk only in the case when we
did not delete a dead record during our walk.

It changes our dynamics a bit:

When deleting a record with non-zero max_dead_records, now we always
leave that number of records around when deleting, doing a blocking
lock on the freelist when we found too many dead records.

Previously when exceeding max_dead_records we wiped all dead records
to start accumulating them from scratch, assuming we could lock the
freelist in a nonblocking fashion.

The net effect for an uncontended freelist is the same: In
tdb_allocate() we still completely hand over all dead records to the
freelist when we could lock it, it just happens later than without
this patch.

This means for a lightly loaded system we will potentially leave more
dead records around in databases like locking.tdb. However, on a
heavily loaded system we become more predictable: If the freelist is
so heavily contended that across many deletes we can't get hold of it,
previously we accumulated more dead records than max_dead_records
would allow. This is a really lowlevel tradeoff that is likely hard to
measure, but to me becoming more deterministic without sacrificing too
much parallelism (we keep more dead records around) is worth trying.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>

Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Tue Oct 30 02:48:38 CET 2018 on sn-devel-144
2018-10-30 02:48:38 +01:00
Volker Lendecke
4ed2a67a59 tdb: Purge dead records whenever we block the freelist
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
2018-10-29 23:36:25 +01:00
Volker Lendecke
8df11518c0 tdb: Remove "USE_RIGHT_MERGES" code
This has not been activated by default for ages and can be very
inefficient. With check_merge_with_left_record() we have an
alternative that will merge freelist records while we walk it
anyway. This has reduced fragmentation significantly

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
2018-10-25 17:58:23 +02:00
Volker Lendecke
a895cc2a59 tdb: Fix a typo
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
2018-10-25 17:58:23 +02:00
Volker Lendecke
7e1ad4c588 tdb: Make the freelist walk circular-safe
We can't really do the full check while the freelist is modified on the
fly. As long as we don't merge any freelist entries, we should be good
to apply this check.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
2018-10-08 22:17:11 +02:00
Volker Lendecke
75e79ca548 tdb: Align integer types
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
2018-10-08 22:17:10 +02:00
Michael Adam
55ff3a3b91 tdb: defragment the freelist in tdb_allocate_from_freelist()
While we are traversing the freelist anyways, merge a record
with the left if it is also a free list record.

That partially makes up for the fragmentation introduced by
the lack of merging with right records in tdb_free().

Note there is a potential slight downside:
If the left record we merge the current record into was earlier
in the chain and has hence already been met in traverse,
then we can not use the enlarged record even if it might be
a new best fit.

Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>

Autobuild-User(master): Volker Lendecke <vl@samba.org>
Autobuild-Date(master): Thu Jun 26 12:16:03 CEST 2014 on sn-devel-104
2014-06-26 12:16:03 +02:00
Michael Adam
56f9231c8e tdb: use tdb_freelist_merge_adjacent in tdb_freelist_size()
So that we automatically defragment the free list when freelist_size is called
(unless the database is read only).

Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2014-06-26 10:00:11 +02:00
Michael Adam
843a8a5c7b tdb: add tdb_freelist_merge_adjacent()
This is intended to be called to reduce the fragmentation in the
freelist. This is to make up the deficiency of the freelist
to be not doubly linked. If the freelist were doubly linked,
we could easily avoid the creation of adjacent freelist entries.
But with the current singly linked list, it is only possible
to cheaply merge a new free record into a freelist entry on the left,
not on the right...

This can be called periodically, e.g. in the vacuuming process
of a ctdb cluster.

Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2014-06-26 10:00:11 +02:00
Michael Adam
73c439f581 tdb: add utility function check_merge_ptr_with_left_record()
Variant of check_merge_with_left_record() that reads the record
itself if necessary.

Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2014-06-26 10:00:11 +02:00
Michael Adam
4bec28bfa9 tdb: simplify tdb_free() using check_merge_with_left_record()
Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2014-06-26 10:00:11 +02:00
Michael Adam
117807cd2d tdb: add utility function check_merge_with_left_record()
Check whether the record left of a given freelist record is
also a freelist record, and if so, merge the two records.

Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2014-06-26 10:00:11 +02:00
Michael Adam
66f3330be8 tdb: improve comments for tdb_free().
Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2014-06-26 10:00:11 +02:00
Michael Adam
8be5c8a6db tdb: factor merge_with_left_record() out of tdb_free()
Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2014-06-26 10:00:11 +02:00
Michael Adam
63673aea9f tdb: fix debug message in tdb_free()
Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2014-06-26 10:00:11 +02:00
Michael Adam
08a76aabe9 tdb: reduce indentation in tdb_free() for merging left
Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2014-06-26 10:00:11 +02:00
Michael Adam
87ac4ac523 tdb: increase readability of read_record_on_left()
by using early returns and better variable names,
and reducing indentation.

Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2014-06-26 10:00:11 +02:00
Michael Adam
f5a777a36c tdb: factor read_record_on_left() out of tdb_free()
Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2014-06-26 10:00:11 +02:00
Michael Adam
d9566085c6 tdb: consolidate tdb allocation code - re-use dead records at hash top.
When in tdb_store we re-use a dead record reactivated from the
target hash chain itself, we currently leave it in its place in
the chain. When we re-use a dead record from a different chain or
from the freelist instead, we insert it at the beginning of the
target chain.

This patch changes the behaviour to always newly store a
record at the beginning of the hash chain. This removes
a special case and hence simplifies the allocation code.
On the other hand side, it introduces two additioal tdb_ofs_write
calls for the in-chain-case.

Note the subtelty of the patch that by moving the case of the candidate
record's chain as new case "i=0" into the for loop, we also reverse the
order of the two steps in the for-loop body (non blocking freelist alloc
and searching for dead record in a chain) in order to keep the overall
order of execution identical.

Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>

Autobuild-User(master): Michael Adam <obnox@samba.org>
Autobuild-Date(master): Wed Apr  9 10:37:08 CEST 2014 on sn-devel-104
2014-04-09 10:37:08 +02:00
Volker Lendecke
3034a5a62b tdb: Reduce freelist contention
In a metadata-intensive benchmark we have seen the locking.tdb freelist to be
one of the central contention points. This patch removes most of the contention
on the freelist. Ages ago we already reduced freelist contention by using the
even much older DEAD records: If TDB_VOLATILE is set, don't directly put
deleted records on the freelist, but just mark a few of them just as DEAD. The
next new record can them re-use that space without consulting the freelist.

This patch builds upon the DEAD records: If we need space and the freelist is
busy, instead of doing a blocking wait on the freelist, start looking into
other chains for DEAD records and steal them from there. This way every hash
chain becomes a small freelist. Just wander around the hash chains as long as
the freelist is still busy.

With this patch and the tdb mutex patch (following hopefully some time soon)
you can see a heavily busy clustered smbd run without locking.tdb futex
syscalls.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Michael Adam <obnox@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
2014-03-18 13:42:10 +01:00
Rusty Russell
3bd686c5ad tdb: fix logging of offets and lengths.
We can have offsets > 2G, so use unsigned values.  Fixes other prints to be
native types rather than casts, too.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

Reviewed-by: Andrew Bartlett <abartlet@samba.org>

Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
Autobuild-Date(master): Tue May 28 11:22:14 CEST 2013 on sn-devel-104
2013-05-28 11:22:14 +02:00
Volker Lendecke
72cd5d5ff6 tdb: Remove "header" from tdb_context
header.hash_size was the only thing we ever referenced outside of
tdb_open_ex and its direct callees. So this shrinks the tdb_context by
164 bytes.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>

Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Tue Feb  5 13:18:28 CET 2013 on sn-devel-104
2013-02-05 13:18:28 +01:00
Volker Lendecke
116ec13bb0 tdb: Fix blank line endings
Reviewed-by: Rusty Russell <rusty@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
2012-12-21 11:54:53 +01:00
Volker Lendecke
2c3fd8a13e tdb: Fix a missing CONVERT
methods->tdb_write expects data in on-disk format. For reading that
record, methods->tdb_read() has taken care of the on-disk to in-memory
representation according to the DOCONV() flag passed down. tdb_rec_write()
is a wrapper around methods->tdb_write just doing the CONVERT() on the
way to disk.

Reviewed-by: Rusty Russell <rusty@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
2012-12-21 11:54:33 +01:00
Rusty Russell
b64494535d tdb: be more careful on 4G files.
I came across a tdb which had wrapped to 4G + 4K, and the contents had been
destroyed by processes which thought it only 4k long.  Fix this by checking
on open, and making tdb_oob() check for wrap itself.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

Autobuild-User: Rusty Russell <rusty@rustcorp.com.au>
Autobuild-Date: Mon Dec 19 07:52:01 CET 2011 on sn-devel-104
2011-12-19 07:52:01 +01:00
Jelmer Vernooij
62c4af9942 tdb: Set _PUBLIC_ in C file rather than header files (Debian bug 600898)
Autobuild-User: Jelmer Vernooij <jelmer@samba.org>
Autobuild-Date: Thu Oct 21 11:47:22 UTC 2010 on sn-devel-104
2010-10-21 11:47:22 +00:00
Volker Lendecke
ea8e0d5d54 Fix some nonempty blank lines 2010-03-25 10:24:45 +01:00
Brad Hards
09e756b1d6 Spelling fixes for tdb.
Signed-off-by: Matthias Dieter Wallnöfer <mwallnoefer@yahoo.de>
2010-02-22 21:45:31 +01:00
Stefan Metzmacher
3b62e250c0 tdb: rename 'struct list_struct' into 'struct tdb_record'
metze
2009-10-23 18:27:20 +02:00
Rusty Russell
b77f41d58b lib/tdb: wean off TDB_ERRCODE.
It was a regrettable hack which I used to reduce line count in tdb; in fact it caused confusion as can be seen in this patch.
In particular, ecode now needs to be set before TDB_LOG anyway, and having it exposed in
the header is useless (the struct tdb_context isn't defined, so it's doubly useless).
Also, we should never set errno, as io.c was doing.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2009-10-22 00:09:43 +10:30
Andrew Tridgell
a6cc04a200 overallocate all records by 25%
This greatly reduces the fragmentation of databases where records
tend to grow slowly by a small amount each time. The case where this
is most seen is the ldb index records. Adding this overallocation
reduced the size of the resulting database by more than 20x when
running a test that adds 10k users.
2009-06-01 13:13:07 +10:00
Jelmer Vernooij
94855cd692 Move common libraries from root to lib/. 2008-09-17 14:11:12 +02:00