From: Mykola Golub Date: Fri, 24 May 2019 06:07:51 +0000 (+0100) Subject: journal: optimize object overflow detection X-Git-Tag: v14.2.3~12^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=152dac5ac651d7c9d1e0a8872da50a19bd9b298a;p=ceph.git journal: optimize object overflow detection Previously to detect overflow we were sending journal append requests until -EOVERFLOW is returned by osd. This means that we had at least one waste (rejected) request per object set (though there may be more if the number of in-flight appends is not limited). We can easily predict when the osd will start to return -EOVERFLOW and avoid such additional requests. Signed-off-by: Mykola Golub (cherry picked from commit 83461c42b03cf7d407ac3c5d02043cca1e908015) --- diff --git a/src/journal/ObjectRecorder.cc b/src/journal/ObjectRecorder.cc index c78b7130886a..e4049df65207 100644 --- a/src/journal/ObjectRecorder.cc +++ b/src/journal/ObjectRecorder.cc @@ -299,7 +299,14 @@ void ObjectRecorder::handle_append_flushed(uint64_t tid, int r) { m_in_flight_flushes_cond.Signal(); if (!m_aio_scheduled) { - if (m_in_flight_appends.empty() && m_object_closed) { + if (m_in_flight_appends.empty() && + (m_object_closed || m_aio_sent_size >= m_soft_max_size)) { + if (m_aio_sent_size >= m_soft_max_size) { + ldout(m_cct, 20) << __func__ << ": " << m_oid + << " soft max size reached, notifying overflow" + << dendl; + m_overflowed = true; + } // all remaining unsent appends should be redirected to new object m_append_buffers.splice(m_append_buffers.begin(), m_pending_buffers); notify_handler_unlock(); @@ -389,6 +396,12 @@ void ObjectRecorder::send_appends_aio() { return; } + if (m_aio_sent_size >= m_soft_max_size) { + ldout(m_cct, 20) << __func__ << ": " << m_oid + << " soft max size reached" << dendl; + return; + } + uint64_t append_tid = m_append_tid++; m_in_flight_tids.insert(append_tid); diff --git a/src/test/journal/test_ObjectRecorder.cc b/src/test/journal/test_ObjectRecorder.cc index 21c741e58963..4b887f151703 100644 --- a/src/test/journal/test_ObjectRecorder.cc +++ b/src/test/journal/test_ObjectRecorder.cc @@ -393,10 +393,8 @@ TEST_F(TestObjectRecorder, Overflow) { shared_ptr lock1(new Mutex("object_recorder_lock_1")); journal::ObjectRecorderPtr object1 = create_object(oid, 12, lock1); - shared_ptr lock2(new Mutex("object_recorder_lock_2")); - journal::ObjectRecorderPtr object2 = create_object(oid, 12, lock2); - std::string payload(2048, '1'); + std::string payload(1 << 11, '1'); journal::AppendBuffer append_buffer1 = create_append_buffer(234, 123, payload); journal::AppendBuffer append_buffer2 = create_append_buffer(234, 124, @@ -411,15 +409,34 @@ TEST_F(TestObjectRecorder, Overflow) { ASSERT_EQ(0, cond.wait()); ASSERT_EQ(0U, object1->get_pending_appends()); + bool overflowed = false; + { + Mutex::Locker locker(m_handler.lock); + while (m_handler.overflows == 0) { + if (m_handler.cond.WaitInterval( + m_handler.lock, utime_t(10, 0)) != 0) { + break; + } + } + if (m_handler.overflows != 0) { + overflowed = true; + m_handler.overflows = 0; + } + } + + ASSERT_TRUE(overflowed); + + shared_ptr lock2(new Mutex("object_recorder_lock_2")); + journal::ObjectRecorderPtr object2 = create_object(oid, 12, lock2); + journal::AppendBuffer append_buffer3 = create_append_buffer(456, 123, payload); append_buffers = {append_buffer3}; - lock2->Lock(); ASSERT_FALSE(object2->append_unlock(std::move(append_buffers))); append_buffer3.first->flush(NULL); - bool overflowed = false; + overflowed = false; { Mutex::Locker locker(m_handler.lock); while (m_handler.overflows == 0) {