Lines Matching full:the
10 This document describes the design and algorithms that the XFS journalling
11 subsystem is based on. This document describes the design and algorithms that
12 the XFS journalling subsystem is based on so that readers may familiarize
13 themselves with the general concepts of how transaction processing in XFS works.
19 the basic concepts covered, the design of the delayed logging mechanism is
26 XFS uses Write Ahead Logging for ensuring changes to the filesystem metadata
27 are atomic and recoverable. For reasons of space and time efficiency, the
29 physical logging mechanisms to provide the necessary recovery guarantees the
32 Some objects, such as inodes and dquots, are logged in logical format where the
33 details logged are made up of the changes to in-core structures rather than
37 finish an operation that was only partially done when the system stopped
40 The reason for these differences is to keep the amount of log space and CPU time
41 required to process objects being modified as small as possible and hence the
44 the overhead of metadata logging low is of prime importance.
46 The method used to log an item or chain modifications together isn't
47 particularly important in the scope of this document. It suffices to know that
48 the method used for logging a particular object or chaining modifications
49 together are different and are dependent on the object and/or modification being
50 performed. The logging subsystem only cares that certain specific rules are
57 XFS has two types of high level transactions, defined by the type of log space
63 The type and size of reservation must be matched to the modification taking
68 In the code, a one-shot transaction pattern looks somewhat like this::
76 As items are modified in the transaction, the dirty regions in those items are
77 tracked via the transaction handle. Once the transaction is committed, all
78 resources joined to it are released, along with the remaining unused reservation
79 space that was taken at the transaction allocation time.
82 transactions, and the pattern looks like this::
105 This results in a series of "rolling transactions" where the inode is locked
106 across the entire chain of transactions. Hence while this series of rolling
107 transactions is running, nothing else can read from or write to the inode and
112 transaction does not form an atomic change in the journal. While each
113 individual modification is atomic, the chain is *not atomic*. If we crash half
114 way through, then recovery will only replay up to the last transactional
115 modification the loop made that was committed to the journal.
119 there is no guarantee of how much of the operation reached stale storage. Hence
121 the high level operation must use intents and deferred operations to guarantee
122 recovery can complete the operation once the first transactions is persisted in
123 the on-disk journal.
130 xfs_trans_commit() does not guarantee that the modification has been committed
131 to stable storage when it returns. Hence when a system crashes, not all the
134 However, the logging subsystem does provide global ordering guarantees, such
141 a "log force" to flush the outstanding committed transactions to stable storage
142 in the journal and wait for that to complete.
145 throughput to the IO latency limitations of the underlying storage. Instead, we
153 It has been mentioned a number of times now that the logging subsystem needs to
155 because it can't be written to the journal due to a lack of space in the
156 journal. This is achieved by the transaction reservations that are made when
158 are maintained as part of the transaction rolling mechanism.
161 available to write the modification into the journal before we start making
162 modifications to objects and items. As such, the reservation needs to be large
163 enough to take into account the amount of metadata that the change might need to
164 log in the worst case. This means that if we are modifying a btree in the
166 of the btree. As such, the reservations are quite complex because we have to
167 take into account all the hidden changes that might occur.
170 free space, which modifies the free space trees. That's two btrees. Inserting
171 the extent into the inode's extent map might require a split of the extent map
172 btree, which requires another allocation that can modify the free space trees
174 another btree which might require more space. And so on. Hence the amount of
177 This "worst case" calculation provides us with the static "unit reservation"
178 for the transaction that is calculated at mount time. We must guarantee that the
179 log has this much space available before the transaction is allowed to proceed
180 so that when we come to write the dirty metadata into the log we don't run out
181 of log space half way through the write.
184 required for the transaction to proceed. For permanent transactions, however, we
185 also have a "log count" that affects the size of the reservation that is to be
189 reservation, it is somewhat inefficient to do this as it requires the
191 know from the implementation of the permanent transactions how many transaction
192 rolls are likely for the common modifications that need to be made.
197 transaction, we might set the reservation log count to a value of 2 to indicate
198 that the common/fast path transaction will commit two linked transactions in a
202 Hence when the permanent transaction is first allocated, the log space
204 reservations. That multiple is defined by the reservation log count, and this
205 means we can roll the transaction multiple times before we have to re-reserve
206 log space when we roll the transaction. This ensures that the common
209 If the log count for a permanent transaction reaches zero, then it needs to
210 re-reserve physical space in the log. This is somewhat complex, and requires
211 an understanding of how the log accounts for space that has been reserved.
217 The position in the log is typically referred to as a Log Sequence Number (LSN).
218 The log is circular, so the positions in the log are defined by the combination
219 of a cycle number - the number of times the log has been overwritten - and the
220 offset into the log. A LSN carries the cycle in the upper 32 bits and the
221 offset in the lower 32 bits. The offset is in units of "basic blocks" (512
223 available space in the log.
225 Log space accounting is done via a pair of constructs called "grant heads". The
226 position of the grant heads is an absolute value, so the amount of space
227 available in the log is defined by the distance between the position of the
228 grant head and the current log tail. That is, how much space can be
229 reserved/consumed before the grant heads would fully wrap the log and overtake
230 the tail position.
232 The first grant head is the "reserve" head. This tracks the byte count of the
234 accounting of the space reservation and, as such, actually tracks byte offsets
235 into the log rather than basic blocks. Hence it technically isn't using LSNs to
236 represent the log position, but it is still treated like a split {cycle,offset}
237 tuple for the purposes of tracking reservation space.
239 The reserve grant head is used to accurately account for exact transaction
240 reservations amounts and the exact byte count that modifications actually make
241 and need to write into the log. The reserve head is used to prevent new
242 transactions from taking new reservations when the head reaches the current
243 tail. It will block new reservations in a FIFO queue and as the log tail moves
248 The other grant head is the "write" head. Unlike the reserve head, this grant
249 head contains an LSN and it tracks the physical space usage in the log. While
250 this might sound like it is accounting the same state as the reserve grant head
251 - and it mostly does track exactly the same location as the reserve grant head -
252 there are critical differences in behaviour between them that provides the
255 These differences when a permanent transaction is rolled and the internal "log
256 count" reaches zero and the initial set of unit reservations have been
258 the next transaction in the sequeunce, but we have none remaining. We cannot
259 sleep during the transaction commit process waiting for new log space to become
260 available, as we may end up on the end of the FIFO queue and the items we have
261 locked while we sleep could end up pinning the tail of the log before there is
262 enough free space in the log to fulfill all of the pending reservations and
267 we need to be able to *overcommit* the log reservation space. As has already
268 been detailed, we cannot overcommit physical log space. However, the reserve
269 grant head does not track physical space - it only accounts for the amount of
270 reservations we currently have outstanding. Hence if the reserve head passes
271 over the tail of the log all it means is that new reservations will be throttled
272 immediately and remain throttled until the log tail is moved forward far enough
273 to remove the overcommit and start taking new reservations. In other words, we
274 can overcommit the reserve head without violating the physical log head and tail
278 xfs_trans_commit() calls, while the physical log space reservation - tracked by
279 the write head - is then reserved separately by a call to xfs_log_reserve()
280 after the commit completes. Once the commit completes, we can sleep waiting for
281 physical log space to be reserved from the write grant head, but only if one
284 Code using permanent reservations must always log the items they hold
285 locked across each transaction they roll in the chain.
287 "Re-logging" the locked items on every transaction roll ensures that the items
288 attached to the transaction chain being rolled are always relocated to the
289 physical head of the log and so do not pin the tail of the log. If a locked item
290 pins the tail of the log when we sleep on the write reservation, then we will
291 deadlock the log as we cannot take the locks needed to write back that item and
292 move the tail of the log forwards to free up write grant space. Re-logging the
293 locked items avoids this deadlock and guarantees that the log reservation we are
297 progress independently because nothing will block the progress of the log
307 the log at any given time. This allows the log to avoid needing to flush each
308 change to disk before recording a new change to the object. XFS does this via a
310 is that any new change to the object is recorded with a *new copy* of all the
311 existing changes in the new transaction that is written to the log.
313 That is, if we have a sequence of changes A through to F, and the object was
314 written to disk after change D, we would see in the log the following series
315 of transactions, their contents and the log sequence number (LSN) of the
327 In other words, each time an object is relogged, the new transaction contains
328 the aggregation of all the previous changes currently held only in the log.
330 This relogging technique allows objects to be moved forward in the log so that
331 an object being relogged does not prevent the tail of the log from ever moving
332 forward. This can be seen in the table above by the changing (increasing) LSN
333 of each subsequent transaction, and it's the technique that allows us to
336 A typical example of a rolling transaction is the removal of extents from an
339 keeps relogging the inode and btree buffers as they get modified in each
340 removal operation. This keeps them moving forward in the log as the operation
341 progresses, ensuring that current operation never gets blocked by itself if the
344 Hence it can be seen that the relogging operation is fundamental to the correct
345 working of the XFS journalling subsystem. From the above description, most
346 people should be able to see why the XFS metadata operations writes so much to
347 the log - repeated operations to the same objects write the same changes to
348 the log over and over again. Worse is the fact that objects tend to get
350 metadata into the log.
353 hand in hand. That is, transactions don't get written to the physical journal
355 transactions) or a synchronous operation forces the log buffers holding the
357 in memory - batching them, if you like - to minimise the impact of the log IO on
360 The limitation on asynchronous transaction throughput is the number and size of
361 log buffers made available by the log manager. By default there are 8 log
362 buffers available and the size of each is 32kB - the size can be increased up
365 Effectively, this gives us the maximum bound of outstanding metadata changes
366 that can be made to the filesystem at any point in time - if all the log
368 the current batch completes. It is now common for a single current CPU core to
369 be to able to issue enough transactions to keep the log buffers full and under
370 IO permanently. Hence the XFS journalling subsystem can be considered to be IO
376 The key thing to note about the asynchronous logging combined with the
378 multiple times before they are committed to disk in the log buffers. If we
379 return to the previous relogging example, it is entirely possible that
380 transactions A through D are committed to disk in the same log buffer.
382 That is, a single log buffer may contain multiple copies of the same object,
383 but only one of those copies needs to be there - the last one "D", as it
384 contains all the changes from the previous changes. In other words, we have one
385 necessary copy in the log buffer, and three stale copies that are simply
386 wasting space. When we are doing repeated operations on the same set of
387 objects, these "stale objects" can be over 90% of the space used in the log
388 buffers. It is clear that reducing the number of stale objects written to the
389 log would greatly reduce the amount of metadata we write to the log, and this
390 is the fundamental goal of delayed logging.
394 logical to physical formatting to do the relogging because there is no
396 formatting the changes in a transaction to the log buffer. Hence we cannot avoid
397 accumulating stale objects in the log buffers.
399 Delayed logging is the name we've given to keeping and tracking transactional
400 changes to objects in memory outside the log buffer infrastructure. Because of
401 the relogging concept fundamental to the XFS journalling subsystem, this is
402 actually relatively easy to do - all the changes to logged items are already
403 tracked in the current infrastructure. The big problem is how to accumulate
404 them and get them to the log in a consistent, recoverable manner.
405 Describing the problems and how they have been solved is the focus of this
408 One of the key changes that delayed logging makes to the operation of the
409 journalling subsystem is that it disassociates the amount of outstanding
410 metadata changes from the size and number of log buffers available. In other
412 written to the log at any point in time, there may be a much greater amount
413 being accumulated in memory. Hence the potential for loss of metadata on a
414 crash is much greater than for the existing logging mechanism.
416 It should be noted that this does not change the guarantee that log recovery
417 will result in a consistent filesystem. What it does mean is that as far as the
419 that simply did not occur as a result of the crash. This makes it even more
424 warrants rigorous proofs to determine whether it is correct or not. The method
425 of accumulating changes in memory for some period before writing them to the
427 no time is spent in this document trying to convince the reader that the
431 The fundamental requirements for delayed logging in XFS are simple:
433 1. Reduce the amount of metadata written to the log by at least
437 problems with the new code.
448 The problem with accumulating changes at a logical level (i.e. just using the
449 existing log item dirty region tracking) is that when it comes to writing the
450 changes to the log buffers, we need to ensure that the object we are formatting
451 is not changing while we do this. This requires locking the object to prevent
452 concurrent modification. Hence flushing the logical changes to the log would
457 the delayed logging tracking lock to commit the transaction. However, the
458 flushing thread has the delayed logging tracking lock already held, and is
459 trying to get the lock on object A to flush it to the log buffer. This appears
461 was the barrier to implementing delayed logging for so long.
463 The solution is relatively simple - it just took a long time to recognise it.
464 Put simply, the current logging code formats the changes to each item into an
465 vector array that points to the changed regions in the item. The log write code
466 simply copies the memory these vectors point to into the log buffer during
467 transaction commit while the item is locked in the transaction. Instead of
468 using the log buffer as the destination of the formatting code, we can use an
469 allocated memory buffer big enough to fit the formatted vector.
471 If we then copy the vector into the memory buffer and rewrite the vector to
472 point to the memory buffer rather than the object itself, we now have a copy of
473 the changes in a format that is compatible with the log buffer writing code.
474 that does not require us to lock the item to access. This formatting and
475 rewriting can all be done while the object is locked during transaction commit,
477 without needing to lock the owning item.
479 Hence we avoid the need to lock items when we need to flush outstanding
480 asynchronous transactions to the log. The differences between the existing
481 formatting method and the delayed logging formatting can be seen in the
509 The memory buffer and associated vector need to be passed as a single object,
510 but still need to be associated with the parent object so if the object is
511 relogged we can replace the current memory buffer with a new memory buffer that
512 contains the latest changes.
514 The reason for keeping the vector around after we've formatted the memory
516 If we don't keep the vector around, we do not know where the region boundaries
517 are in the item, so we'd need a new encapsulation method for regions in the log
519 change and as such is not desirable. It also means we'd have to write the log
520 region headers in the formatting stage, which is problematic as there is per
521 region state that needs to be placed into the headers during the log write.
523 Hence we need to keep the vector, but by attaching the memory buffer to it and
524 rewriting the vector addresses to point at the memory buffer we end up with a
525 self-describing object that can be passed to the log buffer write code to be
526 handled in exactly the same manner as the existing log vectors are handled.
536 them so that they can be written to the log at some later point in time. The
537 log item is the natural place to store this vector and buffer, and also makes sense
538 to be the object that is used to track committed objects as it will always
539 exist once the object has been included in a transaction.
541 The log item is already used to track the log items that have been written to
542 the log but not yet written to disk. Such log items are considered "active"
543 and as such are stored in the Active Item List (AIL) which is a LSN-ordered
546 that is in the AIL can be relogged, which causes the object to be pinned again
547 and then moved forward in the AIL when the log buffer IO completes for that
550 Essentially, this shows that an item that is in the AIL can still be modified
551 and relogged, so any tracking must be separate to the AIL infrastructure. As
552 such, we cannot reuse the AIL list pointers for tracking committed items, nor
553 can we store state in any field that is protected by the AIL lock. Hence the
554 committed item tracking needs its own locks, lists and state fields in the log
557 Similar to the AIL, tracking of committed items is done through a new list
558 called the Committed Item List (CIL). The list tracks log items that have been
561 its place in the list and re-inserted at the tail. This is entirely arbitrary
562 and done to make it easy for debugging - the last items in the list are the
563 ones that are most recently modified. Ordering of the CIL is not necessary for
564 transactional integrity (as discussed in the next section) so the ordering is
565 done for convenience/sanity of the developers.
572 all the items in the CIL must be written into the log via the log buffers.
573 We need to write these items in the order that they exist in the CIL, and they
574 need to be written as an atomic transaction. The need for all the objects to be
575 written as an atomic transaction comes from the requirements of relogging and
576 log replay - all the changes in all the objects in a given transaction must
578 a transaction is not replayed because it is not complete in the log, then
581 To fulfill this requirement, we need to write the entire CIL in a single log
582 transaction. Fortunately, the XFS log code has no fixed limit on the size of a
583 transaction, nor does the log replay code. The only fundamental limit is that
584 the transaction cannot be larger than just under half the size of the log. The
585 reason for this limit is that to find the head and tail of the log, there must
586 be at least one complete transaction in the log at any given time. If a
587 transaction is larger than half the log, then there is the possibility that a
588 crash during the write of a such a transaction could partially overwrite the
589 only complete previous transaction in the log. This will result in a recovery
590 failure and an inconsistent filesystem and hence we must enforce the maximum
591 size of a checkpoint to be slightly less than a half the log.
595 formatted log items and a commit record at the tail. From a recovery
596 perspective, the checkpoint transaction is also no different - just a lot
597 bigger with a lot more items in it. The worst case effect of this is that we
598 might need to tune the recovery transaction object hash size.
600 Because the checkpoint is just another transaction and all the changes to log
601 items are stored as log vectors, we can use the existing log buffer writing
602 code to write the changes into the log. To do this efficiently, we need to
603 minimise the time we hold the CIL locked while writing the checkpoint
604 transaction. The current log write code enables us to do this easily with the
605 way it separates the writing of the transaction contents (the log vectors) from
606 the transaction commit record, but tracking this requires us to have a
607 per-checkpoint context that travels through the log write process through to
610 Hence a checkpoint has a context that tracks the state of the current
612 at the same time a checkpoint transaction is started. That is, when we remove
613 all the current items from the CIL during a checkpoint operation, we move all
614 those changes into the current checkpoint context. We then initialise a new
615 context and attach that to the CIL for aggregation of new transactions.
617 This allows us to unlock the CIL immediately after transfer of all the
619 are formatting the checkpoint into the log. It also allows concurrent
620 checkpoints to be written into the log buffers in the case of log force heavy
621 workloads, just like the existing transaction commit code does. This, however,
622 requires that we strictly order the commit records in the log so that
626 the same time another transaction modifies the item and inserts the log item
627 into the new CIL, then checkpoint transaction commit code cannot use log items
628 to store the list of log vectors that need to be written into the transaction.
630 detached from the log items. That is, when the CIL is flushed the memory
631 buffer and log vector attached to each log item needs to be attached to the
632 checkpoint context so that the log item can be released. In diagrammatic form,
633 the CIL would look like this before the flush::
653 And after the flush the CIL head is empty, and the checkpoint context log
678 Once this transfer is done, the CIL can be unlocked and new transactions can
679 start, while the checkpoint flush code works over the log vector chain to
680 commit the checkpoint.
682 Once the checkpoint is written into the log buffers, the checkpoint context is
683 attached to the log buffer that the commit record was written to along with a
685 run transaction committed processing for the log items (i.e. insert into AIL
686 and unpin) in the log vector chain and then free the log vector chain and
689 Discussion Point: I am uncertain as to whether the log item is the most
690 efficient way to track vectors, even though it seems like the natural way to do
691 it. The fact that we walk the log items (in the CIL) just to chain the log
692 vectors and break the link between the log item and the log vector means that
693 we take a cache line hit for the log item list modification, then another for
694 the log vector chaining. If we track by the log vectors, then we only need to
695 break the link between the log item and the log vector, which means we should
696 dirty only the log item cachelines. Normally I wouldn't be concerned about one
697 vs two dirty cachelines except for the fact I've seen upwards of 80,000 log
700 is in the dev tree....
705 One of the key aspects of the XFS transaction subsystem is that it tags
706 committed transactions with the log sequence number of the transaction commit.
709 committed to the log. In the rare case that a dependent operation occurs (e.g.
711 force can be issued to force the dependent transaction to disk immediately.
713 To do this, transactions need to record the LSN of the commit record of the
714 transaction. This LSN comes directly from the log buffer the transaction is
715 written into. While this works just fine for the existing transaction
717 written directly into the log buffers. Hence some other method of sequencing
720 As discussed in the checkpoint section, delayed logging uses per-checkpoint
722 checkpoint. Because the switching of checkpoint contexts must be done
724 increasing sequence number assigned to it without the need for an external
725 atomic counter - we can just take the current context sequence number and add
726 one to it for the new context.
728 Then, instead of assigning a log buffer LSN to the transaction commit LSN
729 during the commit, we can assign the current checkpoint sequence. This allows
732 result, the code that forces the log to a specific LSN now needs to ensure that
733 the log forces to a specific checkpoint.
735 To ensure that we can do this, we need to track all the checkpoint contexts
736 that are currently committing to the log. When we flush a checkpoint, the
738 checkpoint commit completes, it is removed from the committing list. Because
739 the checkpoint context records the LSN of the commit record for the checkpoint,
740 we can also wait on the log buffer that contains the commit record, thereby
741 using the existing log force mechanisms to execute synchronous forces.
743 It should be noted that the synchronous forces may need to be extended with
744 mitigation algorithms similar to the current log buffer code to allow
746 synchronous transactions being flushed. Investigation of the performance of the
749 The main concern with log forces is to ensure that all the previous checkpoints
750 are also committed to disk before the one we need to wait for. Therefore we
751 need to check that all the prior contexts in the committing list are also
752 complete before waiting on the one we need to complete. We do this
753 synchronisation in the log force code so that we don't need to wait anywhere
756 The only remaining complexity is that a log force now also has to handle the
757 case where the forcing sequence number is the same as the current context. That
758 is, we need to flush the CIL and potentially wait for it to complete. This is a
759 simple addition to the existing log forcing code to check the sequence numbers
760 and push if required. Indeed, placing the current sequence checkpoint flush in
761 the log force code enables the current mechanism for issuing synchronous
763 force the log at the LSN of that transaction) and so the higher level code
764 behaves the same regardless of whether delayed logging is being used or not.
769 The big issue for a checkpoint transaction is the log space reservation for the
771 ahead of time, nor how many log buffers it will take to write out, nor the
772 number of split log vector regions are going to be used. We can track the
773 amount of log space required as we add items to the commit item list, but we
774 still need to reserve the space in the log for the checkpoint.
776 A typical transaction reserves enough space in the log for the worst case space
777 usage of the transaction. The reservation accounts for log record headers,
779 etc. as well as the actual space for all the changed metadata in the
781 the size of the transaction and the number of regions being logged (the number
782 of log vectors in the transaction).
784 An example of the differences would be logging directory changes versus logging
789 vector is 12 bytes, so the total to be logged is approximately 1.75MB. In
794 not particularly flexible and is difficult to select the "optimal value" for
797 Further, if we are going to use a static reservation, which bit of the entire
798 reservation does it cover? We account for space used by the transaction
799 reservation by tracking the space currently used by the object in the CIL and
800 then calculating the increase or decrease in space used as the object is
804 However, even using a static reservation for just the log metadata is
806 1MB of log space consumed (512 bytes per 32k) and the reservation needs to be
808 reservation needs to be made before the checkpoint is started, and we need to
809 be able to reserve the space without sleeping. For a 8MB checkpoint, we need a
812 A static reservation needs to manipulate the log grant counters - we can take a
813 permanent reservation on the space, but we still need to make sure we refresh
814 the write reservation (the actual space available to the transaction) after
816 available when required, then the regrant code will sleep waiting for it.
818 The problem with this is that it can lead to deadlocks as we may need to commit
819 checkpoints to be able to free up log space (refer back to the description of
821 space available in the log if we are to use static reservations, and that is
825 The simpler way of doing this is tracking the entire log space used by the
826 items in the CIL and using this to dynamically calculate the amount of log
827 space required by the log metadata. If this log metadata space changes as a
828 result of a transaction commit inserting a new memory buffer into the CIL, then
829 the difference in space required is removed from the transaction that causes
830 the change. Transactions at this level will *always* have enough space
831 available in their reservation for this as they have already reserved the
833 will always be less than or equal to the maximal amount in the reservation.
835 Hence we can grow the checkpoint transaction reservation dynamically as items
836 are added to the CIL and avoid the need for reserving and regranting log space
837 up front. This avoids deadlocks and removes a blocking point from the
840 As mentioned early, transactions can't grow to more than half the size of the
841 log. Hence as part of the reservation growing, we need to also check the size
842 of the reservation against the maximum allowed transaction size. If we reach
843 the maximum threshold, we need to push the CIL to the log. This is effectively
845 a CIL push triggered by a log force, only that there is no waiting for the
849 If the transaction subsystem goes idle while we still have items in the CIL,
850 they will be flushed by the periodic log force issued by the xfssyncd. This log
851 force will push the CIL to disk, and if the transaction subsystem stays idle,
852 allow the idle log to be covered (effectively marked clean) in exactly the same
853 manner that is done for the existing logging method. A discussion point is
854 whether this log force needs to be done more frequently than the current rate
861 Currently log items are pinned during transaction commit while the items are
862 still locked. This happens just after the items are formatted, though it could
863 be done any time before the items are unlocked. The result of this mechanism is
864 that items get pinned once for every transaction that is committed to the log
865 buffers. Hence items that are relogged in the log buffers will have a pin count
867 transactions is completed, they will unpin the item once. As a result, the item
868 only becomes unpinned when all the transactions complete and there are no
869 pending transactions. Thus the pinning and unpinning of a log item is symmetric
873 completion relationship. Every time an object is relogged in the CIL it goes
874 through the commit process without a corresponding completion being registered.
876 log item completion. The result of this is that pinning and unpinning of the
877 log items becomes unbalanced if we retain the "pin on transaction commit, unpin
880 To keep pin/unpin symmetry, the algorithm needs to change to a "pin on
881 insertion into the CIL, unpin on checkpoint completion". In other words, the
883 pin the object the first time it is inserted into the CIL - if it is already in
884 the CIL during a transaction commit, then we do not pin it again. Because there
886 counts, but as each checkpoint completes the pin count will retain the correct
890 for the pin count means that the pinning of an item must take place under the
891 CIL commit/flush lock. If we pin the object outside this lock, we cannot
892 guarantee which context the pin count is associated with. This is because of
893 the fact pinning the item is dependent on whether the item is present in the
894 current CIL or not. If we don't pin the CIL first before we check and pin the
895 object, we have a race with CIL being flushed between the check and the pin
896 (or not pinning, as the case may be). Hence we must hold the CIL flush/commit
897 lock to guarantee that we pin the items correctly.
902 A fundamental requirement for the CIL is that accesses through transaction
903 commits must scale to many concurrent commits. The current transaction commit
905 processors at once. The current transaction code does not go any faster than if
908 As a result, the delayed logging transaction commit code needs to be designed
909 for concurrency from the ground up. It is obvious that there are serialisation
910 points in the design - the three important ones are:
912 1. Locking out new transaction commits while flushing the CIL
913 2. Adding items to the CIL and updating item space accounting
916 Looking at the transaction commit and CIL flushing interactions, it is clear
917 that we have a many-to-one interaction here. That is, the only restriction on
918 the number of concurrent transactions that can be trying to commit at once is
919 the amount of space available in the log for their reservations. The practical
920 limit here is in the order of several hundred concurrent transactions for a
923 The amount of time a transaction commit needs to hold out a flush is a
924 relatively long period of time - the pinning of log items needs to be done
925 while we are holding out a CIL flush, so at the moment that means it is held
926 across the formatting of the objects into memory buffers (i.e. while memcpy()s
927 are in progress). Ultimately a two pass algorithm where the formatting is done
928 separately to the pinning of objects could be used to reduce the hold time of
929 the transaction commit side.
931 Because of the number of potential transaction commit side holders, the lock
932 really needs to be a sleeping lock - if the CIL flush takes the lock, we do not
933 want every other CPU in the machine spinning on the CIL lock. Given that
934 flushing the CIL could involve walking a list of tens of thousands of log
936 significant concern. Preventing lots of CPUs spinning doing nothing is the
937 main reason for choosing a sleeping lock even though nothing in either the
938 transaction commit or CIL flush side sleeps with the lock held.
943 transaction commit concurrency due to cache line bouncing of the lock on the
946 The second serialisation point is on the transaction commit side where items
947 are inserted into the CIL. Because transactions can enter this code
948 concurrently, the CIL needs to be protected separately from the above
951 possible that this lock will become a contention point, but given the short
954 The final serialisation point is the checkpoint commit record ordering code
955 that is run as part of the checkpoint commit and log force sequencing. The code
956 path that triggers a CIL flush (i.e. whatever triggers the log force) will enter
957 an ordering loop after writing all the log vectors into the log buffers but
958 before writing the commit record. This loop walks the list of committing
961 sequencing also requires the same lock, list walk, and blocking mechanism to
964 These two sequencing operations can use the mechanism even though the
965 events they are waiting for are different. The checkpoint commit record
969 the committing list (i.e. they've completed). A simple wait variable and
971 serialisation queues. They use the same lock as the CIL, too. If we see too
972 much contention on the CIL lock, or too many context switches as a result of
973 the broadcast wakeups these operations can be put under a new spinlock and
974 given separate wait lists to reduce lock contention and the number of processes
975 woken by the wrong event.
981 The existing log item life cycle is as follows::
1021 at the same time step 7 is occurring, but only steps 1-6 or 8-9 can occur
1022 at the same time. If the log item is in the AIL or between steps 6 and 7
1023 and steps 1-6 are re-entered, then the item is relogged. Only when steps 8-9
1024 are entered and completed is the object considered clean.
1026 With delayed logging, there are new steps inserted into the life cycle::
1074 From this, it can be seen that the only life cycle differences between the two
1075 logging methods are in the middle of the life cycle - they still have the same
1076 beginning and end and execution constraints. The only differences are in the
1077 committing of the log items to the log itself and the completion processing.
1082 and the design of the internal structures to avoid on disk format changes, we
1083 can basically switch between delayed logging and the existing mechanism with a
1084 mount option. Fundamentally, there is no reason why the log manager would not