mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 23:52:03 +00:00
dbms: added locks to storages Memory and Log [#CONV-2944].
This commit is contained in:
parent
5aa8c9efc4
commit
7f4348ecdc
@ -81,5 +81,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<Block> Blocks;
|
typedef std::vector<Block> Blocks;
|
||||||
|
typedef std::list<Block> BlocksList;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Poco/File.h>
|
#include <Poco/File.h>
|
||||||
|
#include <Poco/RWLock.h>
|
||||||
|
|
||||||
#include <DB/Core/NamesAndTypes.h>
|
#include <DB/Core/NamesAndTypes.h>
|
||||||
#include <DB/IO/ReadBufferFromFile.h>
|
#include <DB/IO/ReadBufferFromFile.h>
|
||||||
@ -76,6 +77,7 @@ public:
|
|||||||
BlockOutputStreamPtr clone() { return new LogBlockOutputStream(storage); }
|
BlockOutputStreamPtr clone() { return new LogBlockOutputStream(storage); }
|
||||||
private:
|
private:
|
||||||
StorageLog & storage;
|
StorageLog & storage;
|
||||||
|
Poco::ScopedWriteRWLock lock;
|
||||||
|
|
||||||
struct Stream
|
struct Stream
|
||||||
{
|
{
|
||||||
@ -152,6 +154,8 @@ private:
|
|||||||
typedef std::map<String, ColumnData> Files_t;
|
typedef std::map<String, ColumnData> Files_t;
|
||||||
Files_t files;
|
Files_t files;
|
||||||
|
|
||||||
|
Poco::RWLock rwlock;
|
||||||
|
|
||||||
void addFile(const String & column_name, const IDataType & type, size_t level = 0);
|
void addFile(const String & column_name, const IDataType & type, size_t level = 0);
|
||||||
|
|
||||||
/** Прочитать файлы с засечками, если они ещё не прочитаны.
|
/** Прочитать файлы с засечками, если они ещё не прочитаны.
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <Poco/Mutex.h>
|
||||||
|
|
||||||
#include <DB/Core/NamesAndTypes.h>
|
#include <DB/Core/NamesAndTypes.h>
|
||||||
#include <DB/Storages/IStorage.h>
|
#include <DB/Storages/IStorage.h>
|
||||||
#include <DB/DataStreams/IProfilingBlockInputStream.h>
|
#include <DB/DataStreams/IProfilingBlockInputStream.h>
|
||||||
@ -13,16 +15,16 @@ class StorageMemory;
|
|||||||
class MemoryBlockInputStream : public IProfilingBlockInputStream
|
class MemoryBlockInputStream : public IProfilingBlockInputStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MemoryBlockInputStream(const Names & column_names_, Blocks::iterator begin_, Blocks::iterator end_);
|
MemoryBlockInputStream(const Names & column_names_, BlocksList::iterator begin_, BlocksList::iterator end_);
|
||||||
String getName() const { return "MemoryBlockInputStream"; }
|
String getName() const { return "MemoryBlockInputStream"; }
|
||||||
BlockInputStreamPtr clone() { return new MemoryBlockInputStream(column_names, begin, end); }
|
BlockInputStreamPtr clone() { return new MemoryBlockInputStream(column_names, begin, end); }
|
||||||
protected:
|
protected:
|
||||||
Block readImpl();
|
Block readImpl();
|
||||||
private:
|
private:
|
||||||
Names column_names;
|
Names column_names;
|
||||||
Blocks::iterator begin;
|
BlocksList::iterator begin;
|
||||||
Blocks::iterator end;
|
BlocksList::iterator end;
|
||||||
Blocks::iterator it;
|
BlocksList::iterator it;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -72,8 +74,10 @@ private:
|
|||||||
String name;
|
String name;
|
||||||
NamesAndTypesListPtr columns;
|
NamesAndTypesListPtr columns;
|
||||||
|
|
||||||
/// Сами данные
|
/// Сами данные. list - чтобы при вставке в конец, существующие итераторы не инвалидировались.
|
||||||
Blocks data;
|
BlocksList data;
|
||||||
|
|
||||||
|
Poco::FastMutex mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,8 +40,12 @@ Block LogBlockInputStream::readImpl()
|
|||||||
|
|
||||||
/// Если файлы не открыты, то открываем их.
|
/// Если файлы не открыты, то открываем их.
|
||||||
if (streams.empty())
|
if (streams.empty())
|
||||||
|
{
|
||||||
|
Poco::ScopedReadRWLock lock(storage.rwlock);
|
||||||
|
|
||||||
for (Names::const_iterator it = column_names.begin(); it != column_names.end(); ++it)
|
for (Names::const_iterator it = column_names.begin(); it != column_names.end(); ++it)
|
||||||
addStream(*it, *storage.getDataTypeByName(*it));
|
addStream(*it, *storage.getDataTypeByName(*it));
|
||||||
|
}
|
||||||
|
|
||||||
/// Сколько строк читать для следующего блока.
|
/// Сколько строк читать для следующего блока.
|
||||||
size_t max_rows_to_read = std::min(block_size, rows_limit - rows_read);
|
size_t max_rows_to_read = std::min(block_size, rows_limit - rows_read);
|
||||||
@ -117,7 +121,7 @@ void LogBlockInputStream::readData(const String & name, const IDataType & type,
|
|||||||
|
|
||||||
|
|
||||||
LogBlockOutputStream::LogBlockOutputStream(StorageLog & storage_)
|
LogBlockOutputStream::LogBlockOutputStream(StorageLog & storage_)
|
||||||
: storage(storage_)
|
: storage(storage_), lock(storage.rwlock)
|
||||||
{
|
{
|
||||||
for (NamesAndTypesList::const_iterator it = storage.columns->begin(); it != storage.columns->end(); ++it)
|
for (NamesAndTypesList::const_iterator it = storage.columns->begin(); it != storage.columns->end(); ++it)
|
||||||
addStream(it->first, *it->second);
|
addStream(it->first, *it->second);
|
||||||
@ -240,6 +244,8 @@ void StorageLog::addFile(const String & column_name, const IDataType & type, siz
|
|||||||
|
|
||||||
void StorageLog::loadMarks()
|
void StorageLog::loadMarks()
|
||||||
{
|
{
|
||||||
|
Poco::ScopedWriteRWLock lock(rwlock);
|
||||||
|
|
||||||
if (loaded_marks)
|
if (loaded_marks)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -277,6 +283,8 @@ void StorageLog::loadMarks()
|
|||||||
|
|
||||||
void StorageLog::rename(const String & new_path_to_db, const String & new_name)
|
void StorageLog::rename(const String & new_path_to_db, const String & new_name)
|
||||||
{
|
{
|
||||||
|
Poco::ScopedWriteRWLock lock(rwlock);
|
||||||
|
|
||||||
/// Переименовываем директорию с данными.
|
/// Переименовываем директорию с данными.
|
||||||
Poco::File(path + escapeForFileName(name)).renameTo(new_path_to_db + escapeForFileName(new_name));
|
Poco::File(path + escapeForFileName(name)).renameTo(new_path_to_db + escapeForFileName(new_name));
|
||||||
|
|
||||||
@ -302,7 +310,9 @@ BlockInputStreams StorageLog::read(
|
|||||||
check(column_names);
|
check(column_names);
|
||||||
processed_stage = QueryProcessingStage::FetchColumns;
|
processed_stage = QueryProcessingStage::FetchColumns;
|
||||||
|
|
||||||
Marks marks = files.begin()->second.marks;
|
Poco::ScopedReadRWLock lock(rwlock);
|
||||||
|
|
||||||
|
const Marks & marks = files.begin()->second.marks;
|
||||||
size_t marks_size = marks.size();
|
size_t marks_size = marks.size();
|
||||||
|
|
||||||
if (threads > marks_size)
|
if (threads > marks_size)
|
||||||
@ -312,11 +322,6 @@ BlockInputStreams StorageLog::read(
|
|||||||
|
|
||||||
for (size_t thread = 0; thread < threads; ++thread)
|
for (size_t thread = 0; thread < threads; ++thread)
|
||||||
{
|
{
|
||||||
/* std::cerr << "Thread " << thread << ", mark " << thread * marks_size / max_threads
|
|
||||||
<< ", rows " << (thread == 0
|
|
||||||
? marks[marks_size / max_threads - 1].rows
|
|
||||||
: (marks[(thread + 1) * marks_size / max_threads - 1].rows - marks[thread * marks_size / max_threads - 1].rows)) << std::endl;*/
|
|
||||||
|
|
||||||
res.push_back(new LogBlockInputStream(
|
res.push_back(new LogBlockInputStream(
|
||||||
max_block_size,
|
max_block_size,
|
||||||
column_names,
|
column_names,
|
||||||
@ -341,6 +346,8 @@ BlockOutputStreamPtr StorageLog::write(
|
|||||||
|
|
||||||
void StorageLog::drop()
|
void StorageLog::drop()
|
||||||
{
|
{
|
||||||
|
Poco::ScopedWriteRWLock lock(rwlock);
|
||||||
|
|
||||||
for (Files_t::iterator it = files.begin(); it != files.end(); ++it)
|
for (Files_t::iterator it = files.begin(); it != files.end(); ++it)
|
||||||
{
|
{
|
||||||
if (it->second.data_file.exists())
|
if (it->second.data_file.exists())
|
||||||
|
@ -12,7 +12,7 @@ namespace DB
|
|||||||
using Poco::SharedPtr;
|
using Poco::SharedPtr;
|
||||||
|
|
||||||
|
|
||||||
MemoryBlockInputStream::MemoryBlockInputStream(const Names & column_names_, Blocks::iterator begin_, Blocks::iterator end_)
|
MemoryBlockInputStream::MemoryBlockInputStream(const Names & column_names_, BlocksList::iterator begin_, BlocksList::iterator end_)
|
||||||
: column_names(column_names_), begin(begin_), end(end_), it(begin)
|
: column_names(column_names_), begin(begin_), end(end_), it(begin)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -36,6 +36,7 @@ MemoryBlockOutputStream::MemoryBlockOutputStream(StorageMemory & storage_)
|
|||||||
void MemoryBlockOutputStream::write(const Block & block)
|
void MemoryBlockOutputStream::write(const Block & block)
|
||||||
{
|
{
|
||||||
storage.check(block);
|
storage.check(block);
|
||||||
|
Poco::ScopedLock<Poco::FastMutex> lock(storage.mutex);
|
||||||
storage.data.push_back(block);
|
storage.data.push_back(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,16 +57,25 @@ BlockInputStreams StorageMemory::read(
|
|||||||
check(column_names);
|
check(column_names);
|
||||||
processed_stage = QueryProcessingStage::FetchColumns;
|
processed_stage = QueryProcessingStage::FetchColumns;
|
||||||
|
|
||||||
if (threads > data.size())
|
Poco::ScopedLock<Poco::FastMutex> lock(mutex);
|
||||||
threads = data.size();
|
|
||||||
|
size_t size = data.size();
|
||||||
|
|
||||||
|
if (threads > size)
|
||||||
|
threads = size;
|
||||||
|
|
||||||
BlockInputStreams res;
|
BlockInputStreams res;
|
||||||
|
|
||||||
for (size_t thread = 0; thread < threads; ++thread)
|
for (size_t thread = 0; thread < threads; ++thread)
|
||||||
res.push_back(new MemoryBlockInputStream(
|
{
|
||||||
column_names,
|
BlocksList::iterator begin = data.begin();
|
||||||
data.begin() + thread * data.size() / threads,
|
BlocksList::iterator end = data.begin();
|
||||||
data.begin() + (thread + 1) * data.size() / threads));
|
|
||||||
|
std::advance(begin, thread * size / threads);
|
||||||
|
std::advance(end, (thread + 1) * size / threads);
|
||||||
|
|
||||||
|
res.push_back(new MemoryBlockInputStream(column_names, begin, end));
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -80,6 +90,7 @@ BlockOutputStreamPtr StorageMemory::write(
|
|||||||
|
|
||||||
void StorageMemory::drop()
|
void StorageMemory::drop()
|
||||||
{
|
{
|
||||||
|
Poco::ScopedLock<Poco::FastMutex> lock(mutex);
|
||||||
data.clear();
|
data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user