Consolidation Array (C-Array).
More...
|
| const bool | CARRAY_RELEASE_DELEGATION = false |
| |
| tatas_lock | log_core::_flush_lock |
| |
| ConsolidationArray * | log_core::_carray |
| |
| epoch | log_core::_buf_epoch |
| |
| epoch | log_core::_cur_epoch |
| |
| epoch | log_core::_old_epoch |
| |
| void | log_core::_acquire_buffer_space (CArraySlot *info, long size) |
| |
| lsn_t | log_core::_copy_to_buffer (logrec_t &rec, long pos, long size, CArraySlot *info) |
| |
| bool | log_core::_update_epochs (CArraySlot *info) |
| |
| rc_t | log_core::_join_carray (CArraySlot *&info, long &pos, int32_t size) |
| |
| rc_t | log_core::_leave_carray (CArraySlot *info, int32_t size) |
| |
| void | log_core::_copy_raw (CArraySlot *info, long &pos, const char *data, size_t size) |
| |
Consolidation Array (C-Array).
Logging functions/members to implement Consolidation-Array with Decoupled-Buffer-Fill and Delegated-Buffer-Release invented at CMU/EPFL. This technique dramatically reduces the contention in log buffer accesses. For more details, read the Aether paper and its extended version on VLDB Journal.
Acknowledgement
The ideas, performance evaluations, and the initial implementation are solely done by the EPFL team. We just took the implementation and refactored, keeping the main logics.
- See also
- https://bitbucket.org/shoremt/shore-mt/commits/66e5c0aa2f6528cfdbda0907ad338066f14ec066
Differences from [JUNG13]
A few minor details have been changed.
- Separated the core C-Array logics to the classes in this file rather than further bloating log_core.
- CArraySlot (insert_info in original code) places me2 at first so that we can avoid the very tricky (or dubious in portability) offset calculation by union-ing int and pointer. It's simply a reinterpret_cast in our code.
- qnode itself has the status as union so that we don't need hacked_qnode thingy.
- We use Lintel's atomic operations, which have slightly different method signatures. We made according changes to incorporate that.
- Lots of comments added.
Performance Improvements
As of 20140220, with and without this improvement, TPCC on 4-socket machine is as follows (12 worker threads, 3 active slots, CARRAY_RELEASE_DELEGATION=false).
- LOCK-ON: BEFORE=13800 TPS, AFTER=15400 TPS.
- LOCK-OFF: BEFORE=17900 TPS, AFTER=30900 TPS.
- i.e. LOCK-OFF, LOG-OFF: 63000 TPS. So, big improvements in log contention, but not completely removing it. Now lock manager is bigger bottleneck.
Considerations
Among the three techniques, Delegated-Buffer-Release was a bit dubious to be added because, as shown in the Aether paper, it has little benefits in "usual" workload yet adds 10% overheads because of a few more atomic operations. It might be worth the extra 10% for stability in case of highly skewed log sizes, so we should keep an eye. CARRAY_RELEASE_DELEGATION option turns on/off this feature.
Also, consider adjusting the number of active slots depending on the number of worker threads as suggested in the paper. The startup option sm_carray_slots does it. The default value for this option is ConsolidationArray::DEFAULT_ACTIVE_SLOT_COUNT
References
- Ryan Johnson, Ippokratis Pandis, Radu Stoica, Manos Athanassoulis, and Anastasia Ailamaki. "Aether: a scalable approach to logging." Proceedings of the VLDB Endowment 3, no. 1-2 (2010): 681-692.
- Ryan Johnson, Ippokratis Pandis, Radu Stoica, Manos Athanassoulis, and Anastasia Ailamaki. "Scalability of write-ahead logging on multicore and multisocket hardware." The VLDB Journal 21, no. 2 (2012): 239-263.
§ carray_slotid_t
§ carray_status_t
An integer to represents the status of one C-Array slot.
The high 32 bits represent the number of threads joining the group. The low 32 bits represent the total number of bytes of the logs in the group. We combine the two information to one 64bit integer for efficient atomic operations. A C-Array slot is available for new use only when this status value is exactly 0 (SLOT_AVAILABLE). Negative values have special meanings. See the constants below.
- See also
- CArraySlot
-
ConsolidationArray::Constants
§ _acquire_buffer_space()
| void log_core::_acquire_buffer_space |
( |
CArraySlot * |
info, |
|
|
long |
size |
|
) |
| |
|
protected |
§ _copy_raw()
| void log_core::_copy_raw |
( |
CArraySlot * |
info, |
|
|
long & |
pos, |
|
|
const char * |
data, |
|
|
size_t |
size |
|
) |
| |
|
protected |
§ _copy_to_buffer()
§ _join_carray()
| rc_t log_core::_join_carray |
( |
CArraySlot *& |
info, |
|
|
long & |
pos, |
|
|
int32_t |
size |
|
) |
| |
|
protected |
§ _leave_carray()
§ _update_epochs()
| bool log_core::_update_epochs |
( |
CArraySlot * |
info | ) |
|
|
protected |
§ _buf_epoch
| epoch log_core::_buf_epoch |
|
protected |
§ _carray
Consolidation array for this log manager.
§ _cur_epoch
| epoch log_core::_cur_epoch |
|
protected |
§ _flush_lock
§ _old_epoch
| epoch log_core::_old_epoch |
|
protected |
§ CARRAY_RELEASE_DELEGATION
| const bool CARRAY_RELEASE_DELEGATION = false |
Whether to enable Delegated-Buffer-Release.
CS: in plog approach (Atomic Commit Protocol), delegated buffer releases become crucial, since the total log volume of each transactions is more likely to vary considerably. In the old approach, the technique is only important in individual log record size (and not the sum of all log records of a transaction) varies too much.