dbwrap_ctdb: only fetch a read-only copy if we had a record already.
authorRusty Russell <rusty@rustcorp.com.au>
Fri, 3 Feb 2012 00:00:54 +0000 (11:00 +1100)
committerAmitay Isaacs <amitay@samba.org>
Mon, 5 Mar 2012 00:11:26 +0000 (01:11 +0100)
Because revoking read-only copies of records is expensive, we only
want ctdbd to do it for high-turnover records.  A basic heuristic is
that if we don't find a local copy of the record, don't ask for a
read-only copy.

The fetch itself will cause ctdbd to migrate the record, so eventually
we will have a local copy.  Next time it gets migrated away, we'll
call ctdbd_fetch() with local_copy = true.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
source3/include/ctdbd_conn.h
source3/lib/ctdbd_conn.c
source3/lib/dbwrap/dbwrap_ctdb.c

index 9a3c27cdb99ad9a0c4a57ef5295b85bcebe6bfca..2035e8ddfc3adcaca6f6c881d77f691e3736dc08 100644 (file)
@@ -60,7 +60,8 @@ NTSTATUS ctdbd_migrate(struct ctdbd_connection *conn, uint32 db_id,
                       TDB_DATA key);
 
 NTSTATUS ctdbd_fetch(struct ctdbd_connection *conn, uint32 db_id,
-                    TDB_DATA key, TALLOC_CTX *mem_ctx, TDB_DATA *data);
+                    TDB_DATA key, TALLOC_CTX *mem_ctx, TDB_DATA *data,
+                    bool local_copy);
 
 NTSTATUS ctdbd_traverse(uint32 db_id,
                        void (*fn)(TDB_DATA key, TDB_DATA data,
index f160fd6151282db589ef6a22f56e038b52d09b9d..47090a5412c8c77bdcfd8abdca55e0e1908b6f3d 100644 (file)
@@ -1394,7 +1394,8 @@ NTSTATUS ctdbd_migrate(struct ctdbd_connection *conn, uint32 db_id,
  * remotely fetch a record (read-only)
  */
 NTSTATUS ctdbd_fetch(struct ctdbd_connection *conn, uint32 db_id,
-                    TDB_DATA key, TALLOC_CTX *mem_ctx, TDB_DATA *data)
+                    TDB_DATA key, TALLOC_CTX *mem_ctx, TDB_DATA *data,
+                    bool local_copy)
 {
        struct ctdb_req_call req;
        struct ctdb_reply_call *reply;
@@ -1407,7 +1408,7 @@ NTSTATUS ctdbd_fetch(struct ctdbd_connection *conn, uint32 db_id,
        req.hdr.ctdb_version = CTDB_VERSION;
        req.hdr.operation    = CTDB_REQ_CALL;
        req.hdr.reqid        = ctdbd_next_reqid(conn);
-       req.flags            = CTDB_WANT_READONLY;
+       req.flags            = local_copy ? CTDB_WANT_READONLY : 0;
        req.callid           = CTDB_FETCH_FUNC;
        req.db_id            = db_id;
        req.keylen           = key.dsize;
index 0f4efa359cca7d26e393ccc464aada28e08ef2c3..a05f9554b7639432c883d9406069eca24e2cd928 100644 (file)
@@ -1203,9 +1203,14 @@ static NTSTATUS db_ctdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
 
        SAFE_FREE(ctdb_data.dptr);
 
-       /* we weren't able to get it locally - ask ctdb to fetch it for us */
+       /*
+        * We weren't able to get it locally - ask ctdb to fetch it for us.
+        * If we already had *something*, it's probably worth making a local
+        * read-only copy.
+        */
        status = ctdbd_fetch(messaging_ctdbd_connection(), ctx->db_id, key,
-                            mem_ctx, data);
+                            mem_ctx, data,
+                            ctdb_data.dsize >= sizeof(struct ctdb_ltdb_header));
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5, ("ctdbd_fetch failed: %s\n", nt_errstr(status)));
        }