1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

Leave sequence number alone when merely migrating records.

(Based on earlier version from Ronnie which modified tdb; this one
is standalone).

When storing records in a tdb that has "automatic seqnum updates"
also check if the actual data for the record has changed or not.

If it has not changed at all, except for possibly the header,
this is likely just a dmaster migration operation in which case
we want to write the record to the tdb but we do not want the tdb
sequence number to be increased.

This resolves the problem of notify.tdb being thrashed under load:
the heuristic in smbd to only reread this when the sequence number
increases (rarely) breaks down.

Before, running nbench --num-progs=512 across 4 nodes, we saw numbers like:
 512      1496  118.33 MB/sec  execute 60 sec  latency 0.00 msec
And turning on latency tracking, this was typical in the logs:
 ctdbd: High latency 9380914.000000s for operation lockwait on database notify.tdb

After this commit:
  512      2451  143.85 MB/sec  execute 60 sec  latency 0.00 msec
And no more latency messages...

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

(This used to be ctdb commit 9ed2f8b2fcb7e3f0d795eef22cfa317066490709)
This commit is contained in:
Rusty Russell 2010-02-12 17:02:56 +10:30 committed by Ronnie Sahlberg
parent 96a61ca907
commit 435fb78d13

View File

@ -128,6 +128,7 @@ int ctdb_ltdb_store(struct ctdb_db_context *ctdb_db, TDB_DATA key,
struct ctdb_context *ctdb = ctdb_db->ctdb; struct ctdb_context *ctdb = ctdb_db->ctdb;
TDB_DATA rec; TDB_DATA rec;
int ret; int ret;
bool seqnum_suppressed = false;
if (ctdb->flags & CTDB_FLAG_TORTURE) { if (ctdb->flags & CTDB_FLAG_TORTURE) {
struct ctdb_ltdb_header *h2; struct ctdb_ltdb_header *h2;
@ -147,10 +148,28 @@ int ctdb_ltdb_store(struct ctdb_db_context *ctdb_db, TDB_DATA key,
memcpy(rec.dptr, header, sizeof(*header)); memcpy(rec.dptr, header, sizeof(*header));
memcpy(rec.dptr + sizeof(*header), data.dptr, data.dsize); memcpy(rec.dptr + sizeof(*header), data.dptr, data.dsize);
/* Databases with seqnum updates enabled only get their seqnum
changes when/if we modify the data */
if (ctdb_db->seqnum_update != NULL) {
TDB_DATA old;
old = tdb_fetch(ctdb_db->ltdb->tdb, key);
if ( (old.dsize == rec.dsize)
&& !memcmp(old.dptr+sizeof(struct ctdb_ltdb_header),
rec.dptr+sizeof(struct ctdb_ltdb_header),
rec.dsize-sizeof(struct ctdb_ltdb_header)) ) {
tdb_remove_flags(ctdb_db->ltdb->tdb, TDB_SEQNUM);
seqnum_suppressed = true;
}
if (old.dptr) free(old.dptr);
}
ret = tdb_store(ctdb_db->ltdb->tdb, key, rec, TDB_REPLACE); ret = tdb_store(ctdb_db->ltdb->tdb, key, rec, TDB_REPLACE);
if (ret != 0) { if (ret != 0) {
DEBUG(DEBUG_ERR, (__location__ " Failed to store dynamic data\n")); DEBUG(DEBUG_ERR, (__location__ " Failed to store dynamic data\n"));
} }
if (seqnum_suppressed) {
tdb_add_flags(ctdb_db->ltdb->tdb, TDB_SEQNUM);
}
talloc_free(rec.dptr); talloc_free(rec.dptr);