When collecting the list of log records to be replayed, single-page recovery uses the log_core::fetch method, which reads into an internal buffer and returns a pointer into this buffer. The idea is that the caller must release the partition lock once it's done with the log record, so that the buffer can be reused for further fetches. However, single-page recovery immediately releases the partition lock, and only after some further processing it copies the log record contents into its own buffer. In a scenario of high concurrency, another thread may perform a fetch in-between, which invalidates the buffer, resulting in incorrect single-page recovery.
There are two possible solutions: either (a) the partition lock is kept until the log record contents are copied; or (b) single-page recovery immediately copies into its own buffer prior to releasing the lock, performing the required processing on the copied (thread-safe) contents.
When collecting the list of log records to be replayed, single-page recovery uses the
log_core::fetch
method, which reads into an internal buffer and returns a pointer into this buffer. The idea is that the caller must release the partition lock once it's done with the log record, so that the buffer can be reused for further fetches. However, single-page recovery immediately releases the partition lock, and only after some further processing it copies the log record contents into its own buffer. In a scenario of high concurrency, another thread may perform a fetch in-between, which invalidates the buffer, resulting in incorrect single-page recovery.There are two possible solutions: either (a) the partition lock is kept until the log record contents are copied; or (b) single-page recovery immediately copies into its own buffer prior to releasing the lock, performing the required processing on the copied (thread-safe) contents.