]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
journal: optimize object overflow detection
authorMykola Golub <mgolub@suse.com>
Fri, 24 May 2019 06:07:51 +0000 (07:07 +0100)
committerJason Dillaman <dillaman@redhat.com>
Mon, 19 Aug 2019 15:12:59 +0000 (11:12 -0400)
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 <mgolub@suse.com>
(cherry picked from commit 83461c42b03cf7d407ac3c5d02043cca1e908015)

src/journal/ObjectRecorder.cc
src/test/journal/test_ObjectRecorder.cc

index c78b7130886ab3b0bfbd785602c47e49e5cd6772..e4049df65207ceea019a7ded9245e47fc527a0d5 100644 (file)
@@ -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);
 
index 21c741e5896377462c64327e8976a791ebd8c32c..4b887f151703718e840fbe3f4b5186fb6e319b6e 100644 (file)
@@ -393,10 +393,8 @@ TEST_F(TestObjectRecorder, Overflow) {
 
   shared_ptr<Mutex> lock1(new Mutex("object_recorder_lock_1"));
   journal::ObjectRecorderPtr object1 = create_object(oid, 12, lock1);
-  shared_ptr<Mutex> 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<Mutex> 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) {