I mentioned earlier that RVM provides opportunities
for the developer to give hints to
the library on optimizing the performance of
the library for the chosen application. Or
in other words, the transaction semantics of
RVN is already a stripped-down version of
the traditional transaction semantic. It doesn't what
you are able nested transaction and so on,
but still transaction by it's very nature requires that
a commit point, you have to do a synchronous
to the I/O to the disc. And similarly transaction
by it's very nature says that, it has an all
or nothing property. So the transaction is not going
to commit, that is that it's going to abort, then
we have to make sure that all the changes
that have been made between begin transaction and abort transaction
are thrown away. And similarly, if the transaction
commits, then we have to make sure that at
the commit point all of the changes that have
been made to in memory copies of persistent data
structures are committed to the disk. That's where
synchronous I/O comes in. But if the developer wants
to optimize his performance, RVM gives opportunities for such
optimizations. The first opportunity is the no_restore mode in
the begin_xact call. The no_restore mode in begin_xact is
signalling to RVN that this transaction that I am
starting is not going to abort, and therefore there
is no need for you to create an in
memory, undo record for me. Even though I am
going to give you a set range call, don't bother
creating an undo record for the range of addresses
that I intend to modify in this beginning transaction.
That's what is meant by the no_restore mode. So
that reduce the amount of work that the RVM
has to do in doing a memory copy and
the application is going to gain because RVM is
doing less work which means the overhead in performing
a transaction is going to be less as seen
by the application. The second optimization opportunity is a
no-flush mode in the end transaction. As I mentioned,
a transaction truly has committed only when
the changes to the critical section between
begin transaction and end transaction have been
synchronously written out to the disk. So, the
normal semantic of an end transaction, that is a commit of a transaction, would
require that our VM should block the
process that made that call for end transaction,
until that redo record has been written synchronously to the disk.
But if the application developer is opportunistic and believes
that the chances of failure either due to power
failure or due to his own software caching is pretty small, he could be brave
enough to say no-flush mode. And what that no-flush mode is telling the RVM
library is that there is no need to do a
synchronous I/O. Of course I want you to write it to
the disk but don't block me in order to write
to the disk. So no need to do the synchronous flash
of the redo log to the disk. And, in other
words, what we're getting by doing a no-flush mode in end
transaction is lazy persistence. We know it is going to
be persistent on the disk, that is the work that RVM
is going to do, but it is not doing it
exactly at the point of end transaction. So the
upshot is, there is a window of vulnerability. End
transaction happened here, and maybe by the time RVM
gets to write it out to the disk, so
much time has elapsed. So this time window is
the window of vulnerability. So if this axis is
time, then n transaction happened here, and this is
the point where the redo record was committed to
the disk, so this is the portion which we're calling
as a window of vulnerability, and the app developer
is taking a chance, saying that I am so sure
that no crash is going to happen in this window,
I'm going to go ahead and say no-flush. So, in other
words, the transaction is being used as an insurance, and
this should remind you of the old at the age
that we saw when we talked about shared memory systems. Shared memory systems
scale really well when you don't share
memory. Similarly, transactional systems scale really well,
perform really well, when you don't use
the full semantic requirement of transaction, in
particular if you can get rid of
synchronous I/O, it'll make the performance better.