{
TALLOC_CTX *tmp_ctx = talloc_new(h);
struct ctdb_ltdb_header header;
+ TDB_DATA olddata;
int ret;
ZERO_STRUCT(header);
/* we need the header so we can update the RSN */
- ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, tmp_ctx, NULL);
+ ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, tmp_ctx, &olddata);
if (ret == -1 && header.dmaster == (uint32_t)-1) {
/* the record doesn't exist - create one with us as dmaster.
This is only safe because we are in a transaction and this
return ret;
}
+ if (data.dsize == olddata.dsize &&
+ memcmp(data.dptr, olddata.dptr, data.dsize) == 0) {
+ /* save writing the same data */
+ talloc_free(tmp_ctx);
+ return 0;
+ }
+
header.rsn++;
if (!h->in_replay) {
talloc_free(tmp_ctx);
return -1;
}
-
- h->m_write = ctdb_marshall_add(h, h->m_write, h->ctdb_db->db_id, 0, key, &header, data);
- if (h->m_write == NULL) {
- DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
- talloc_free(tmp_ctx);
- return -1;
- }
+ }
+
+ h->m_write = ctdb_marshall_add(h, h->m_write, h->ctdb_db->db_id, 0, key, &header, data);
+ if (h->m_write == NULL) {
+ DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
+ talloc_free(tmp_ctx);
+ return -1;
}
ret = ctdb_ltdb_store(h->ctdb_db, key, &header, data);
struct ctdb_rec_data *rec = NULL;
h->in_replay = true;
+ talloc_free(h->m_write);
+ h->m_write = NULL;
ret = ctdb_transaction_fetch_start(h);
if (ret != 0) {
struct ctdb_context *ctdb = h->ctdb_db->ctdb;
struct timeval timeout;
- if (h->m_write == NULL) {
- /* no changes were made */
- talloc_free(h);
- return 0;
- }
-
talloc_set_destructor(h, NULL);
/* our commit strategy is quite complex.
*/
again:
+ if (h->m_write == NULL) {
+ /* no changes were made */
+ tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
+ talloc_free(h);
+ return 0;
+ }
+
/* tell ctdbd to commit to the other nodes */
timeout = timeval_current_ofs(1, 0);
ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,