Guarantees inside a transaction

19 views
Skip to first unread message

Dimitris Stavrakakis

unread,
Jun 25, 2020, 10:25:55 AM6/25/20
to pmem
Hello everyone,
it might be a simple question but I got a little bit confused while thinking the most proper way to handle objects inside a transaction.
Let me show you the following two code examples:

struct my_root {
char buf[MAX_BUF_LEN_ROOT];
};
PMEMoid root = pmemobj_root(pop, size);
struct my_root *rootp = pmemobj_direct(root);

char* root_obj_data = malloc(MAX_BUF_LEN_ROOT * sizeof(char));
strcpy(root_obj_data, "Root_Object_Data");

TX_BEGIN(pop) {
pmemobj_tx_add_range(root, 0, sizeof(struct my_root));
memcpy(rootp->buf, root_obj_data, MAX_BUF_LEN_ROOT);
} TX_END

TX_BEGIN(pop) {
memcpy(rootp->buf, root_obj_data, MAX_BUF_LEN_ROOT);
pmemobj_persist(pop, rootp, sizeof(struct my_root));
} TX_END

I would like to ask you, what is the difference between the first transaction body with the second one?
I know that in the first option the content of the object is being logged in the undo log for the unfortunate case of a power-failure or an unexpected crash.
In the second option there is no such logging but the pmemobj_persist is called inside of the transaction for an object with size larger than the 8byte atomic write.
As far as I understand, the second case does not guarantee the consistency of the object in the case of a failure since there is no entry in the undo log and the write is not atomic.
In the transaction bodies, everything should be snapshotted in order be consistent even in the case of the crash. Is that correct?
Do I misundestand something?

Thank you a lot in advance.
I am looking forward to your response.

Dimitris



ppbb...@gmail.com

unread,
Jun 25, 2020, 10:42:16 AM6/25/20
to pmem
Hi,
You described it exactly right. In the second case the state of the roop->buf is undefined in the case of a failure.

Piotr
Reply all
Reply to author
Forward
0 new messages