Skip to content

Commit

Permalink
Merge pull request ClickHouse#39834 from ClickHouse/backport/22.3/39800
Browse files Browse the repository at this point in the history
Backport ClickHouse#39800 to 22.3: Fix `CANNOT_READ_ALL_DATA` with `pread_threadpool`.
  • Loading branch information
alexey-milovidov authored Aug 3, 2022
2 parents 201daa1 + 03233e0 commit 2a83062
Showing 1 changed file with 17 additions and 1 deletion.
18 changes: 17 additions & 1 deletion src/Disks/IO/ThreadPoolReader.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "ThreadPoolReader.h"
#include <Common/VersionNumber.h>
#include <Common/assert_cast.h>
#include <Common/Exception.h>
#include <Common/ProfileEvents.h>
Expand All @@ -7,6 +8,7 @@
#include <Common/setThreadName.h>
#include <Common/MemorySanitizer.h>
#include <Common/CurrentThread.h>
#include <Poco/Environment.h>
#include <base/errnoToString.h>
#include <Poco/Event.h>
#include <future>
Expand Down Expand Up @@ -71,6 +73,16 @@ namespace ErrorCodes

}

#if defined(OS_LINUX)
/// According to man, Linux 5.9 and 5.10 have a bug in preadv2() with the RWF_NOWAIT.
/// https://manpages.debian.org/testing/manpages-dev/preadv2.2.en.html#BUGS
/// We also disable it for older Linux kernels, because according to user's reports, RedHat-patched kernels might be also affected.
static bool hasBugInPreadV2()
{
VersionNumber linux_version(Poco::Environment::osVersion());
return linux_version < VersionNumber{5, 11, 0};
}
#endif

ThreadPoolReader::ThreadPoolReader(size_t pool_size, size_t queue_size_)
: pool(pool_size, pool_size, queue_size_)
Expand All @@ -88,7 +100,11 @@ std::future<IAsynchronousReader::Result> ThreadPoolReader::submit(Request reques
/// Check if data is already in page cache with preadv2 syscall.

/// We don't want to depend on new Linux kernel.
static std::atomic<bool> has_pread_nowait_support{true};
/// But kernels 5.9 and 5.10 have a bug where preadv2() with the
/// RWF_NOWAIT flag may return 0 even when not at end of file.
/// It can't be distinguished from the real eof, so we have to
/// disable pread with nowait.
static std::atomic<bool> has_pread_nowait_support = !hasBugInPreadV2();

if (has_pread_nowait_support.load(std::memory_order_relaxed))
{
Expand Down

0 comments on commit 2a83062

Please sign in to comment.