ClickHouse/src/Storages/PostgreSQL/PostgreSQLReplicaConsumer.h

127 lines
3.9 KiB
C++
Raw Normal View History

#pragma once
2021-02-18 06:06:37 +00:00
#if !defined(ARCADIA_BUILD)
#include "config_core.h"
#endif
#if USE_LIBPQXX
2021-01-19 15:29:22 +00:00
#include "PostgreSQLConnection.h"
2021-02-03 16:13:18 +00:00
#include "PostgreSQLReplicaMetadata.h"
2021-02-18 06:06:37 +00:00
#include "insertPostgreSQLValue.h"
2021-02-06 12:28:42 +00:00
#include <Core/BackgroundSchedulePool.h>
#include <common/logger_useful.h>
2021-01-31 19:03:03 +00:00
#include <Storages/IStorage.h>
#include <DataStreams/OneBlockInputStream.h>
2021-02-13 20:46:52 +00:00
#include <Parsers/ASTExpressionList.h>
2021-02-18 06:06:37 +00:00
#include "pqxx/pqxx" // Y_IGNORE
2021-02-06 12:28:42 +00:00
namespace DB
{
class PostgreSQLReplicaConsumer
{
public:
using Storages = std::unordered_map<String, StoragePtr>;
PostgreSQLReplicaConsumer(
std::shared_ptr<Context> context_,
2021-02-04 17:17:16 +00:00
PostgreSQLConnectionPtr connection_,
const std::string & replication_slot_name_,
const std::string & publication_name_,
2021-02-03 16:13:18 +00:00
const std::string & metadata_path,
2021-02-06 12:28:42 +00:00
const std::string & start_lsn,
2021-01-31 19:03:03 +00:00
const size_t max_block_size_,
Storages storages_);
void startSynchronization();
2021-02-08 23:23:51 +00:00
void stopSynchronization();
private:
2021-02-08 23:23:51 +00:00
void synchronizationStream();
2021-02-03 16:13:18 +00:00
bool readFromReplicationSlot();
2021-02-08 23:23:51 +00:00
void syncTables(std::shared_ptr<pqxx::nontransaction> tx);
String advanceLSN(std::shared_ptr<pqxx::nontransaction> ntx);
2021-02-08 23:23:51 +00:00
void processReplicationMessage(const char * replication_message, size_t size);
2021-02-03 16:13:18 +00:00
struct BufferData
{
ExternalResultDescription description;
MutableColumns columns;
2021-02-13 20:46:52 +00:00
std::shared_ptr<ASTExpressionList> columnsAST;
/// Needed for insertPostgreSQLValue() method to parse array
std::unordered_map<size_t, PostgreSQLArrayInfo> array_info;
2021-02-13 20:46:52 +00:00
BufferData(StoragePtr storage)
{
2021-02-13 20:46:52 +00:00
const auto storage_metadata = storage->getInMemoryMetadataPtr();
description.init(storage_metadata->getSampleBlock());
columns = description.sample_block.cloneEmptyColumns();
2021-02-13 20:46:52 +00:00
const auto & storage_columns = storage_metadata->getColumns().getAllPhysical();
auto insert_columns = std::make_shared<ASTExpressionList>();
size_t idx = 0;
assert(description.sample_block.columns() == storage_columns.size());
for (const auto & column : storage_columns)
{
if (description.types[idx].first == ExternalResultDescription::ValueType::vtArray)
preparePostgreSQLArrayInfo(array_info, idx, description.sample_block.getByPosition(idx).type);
2021-02-13 20:46:52 +00:00
idx++;
insert_columns->children.emplace_back(std::make_shared<ASTIdentifier>(column.name));
}
columnsAST = std::move(insert_columns);
}
};
using Buffers = std::unordered_map<String, BufferData>;
2021-02-18 18:20:52 +00:00
static void insertDefaultValue(BufferData & buffer, size_t column_idx);
static void insertValue(BufferData & buffer, const std::string & value, size_t column_idx);
2021-01-31 19:03:03 +00:00
2021-02-08 23:23:51 +00:00
enum class PostgreSQLQuery
{
INSERT,
UPDATE,
DELETE
};
void readTupleData(BufferData & buffer, const char * message, size_t & pos, size_t size, PostgreSQLQuery type, bool old_value = false);
2021-02-18 18:20:52 +00:00
static void readString(const char * message, size_t & pos, size_t size, String & result);
static Int64 readInt64(const char * message, size_t & pos, size_t size);
static Int32 readInt32(const char * message, size_t & pos, size_t size);
static Int16 readInt16(const char * message, size_t & pos, size_t size);
static Int8 readInt8(const char * message, size_t & pos, size_t size);
2021-01-27 15:29:28 +00:00
Poco::Logger * log;
std::shared_ptr<Context> context;
2021-02-08 23:23:51 +00:00
const std::string replication_slot_name, publication_name;
2021-02-08 23:23:51 +00:00
PostgreSQLReplicaMetadata metadata;
2021-02-04 17:17:16 +00:00
PostgreSQLConnectionPtr connection;
2021-02-06 12:28:42 +00:00
std::string current_lsn, final_lsn;
const size_t max_block_size;
2021-02-08 23:23:51 +00:00
std::string table_to_insert;
2021-02-08 23:23:51 +00:00
std::unordered_set<std::string> tables_to_sync;
2021-01-27 15:29:28 +00:00
BackgroundSchedulePool::TaskHolder wal_reader_task;
std::atomic<bool> stop_synchronization = false;
2021-01-31 19:03:03 +00:00
Storages storages;
Buffers buffers;
};
}
2021-02-18 06:06:37 +00:00
#endif