UDP2 is a next-generation interconnect protocol implementation based on the original UDP protocol, located in the contrib/udp2 directory. In Apache Cloudberry, the interconnect is responsible for data transmission and synchronization between nodes, serving as a core component for distributed query execution.
Currently, the database supports three interconnect protocol implementations:
contrib/interconnect/tcp) - Reliable transmission based on TCP protocolcontrib/interconnect/udp) - High-performance transmission based on UDP protocolcontrib/interconnect/proxy) - Proxy-based transmissionUDP2 is an architectural refactoring based on the original UDP protocol implementation, aimed at achieving complete separation between interconnect and the database kernel.
The core objectives of the UDP2 protocol implementation are:
UDP2 adopts a layered architecture design, primarily divided into two layers:
┌─────────────────────────────────────────────────────────┐
│ Database Kernel Layer │
│ ┌────────────────────────────────────────────────────┐ │
│ │ contrib/udp2/ │ │
│ │ ┌─────────────────┐ ┌────────────────────────┐ │ │
│ │ │ ic_modules.c │ │ ic_udp2.c │ │ │
│ │ │ ic_modules.h │ │ ic_udp2.h │ │ │
│ │ └─────────────────┘ └────────────────────────┘ │ │
│ │ Adapter Layer (Database Adapter) │ │
│ └────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
│
│ C/C++ Interface
▼
┌──────────────────────────────────────────────────────────┐
│ Independent IC Communication Library │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ contrib/udp2/ic_common/ │ │
│ │ ┌─────────────────┐ ┌─────────────────────────┐ │ │
│ │ │ ic_types.h │ │ ic_utility.hpp │ │ │
│ │ │ ic_except.hpp │ │ ic_faultinjection.h │ │ │
│ │ └─────────────────┘ └─────────────────────────┘ │ │
│ │ ┌────────────────────────────────────────────────┐ │ │
│ │ │ contrib/udp2/ic_common/udp2/ │ │ │
│ │ │ ┌─────────────────┐ ┌─────────────────────┐ │ │ │
│ │ │ │ ic_udp2.h │ │ ic_udp2.hpp │ │ │ │
│ │ │ │ ic_udp2.cpp │ │ic_udp2_internal.hpp │ │ │ │
│ │ │ └─────────────────┘ └─────────────────────┘ │ │ │
│ │ └────────────────────────────────────────────────┘ │ │
│ │ Core Communication Library │ │
│ └─────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
contrib/udp2/)MotionIPCLayer interfacecontrib/udp2/ic_common/)contrib/udp2/ic_common/udp2/)UDP2 uses CMake build system with support for independent compilation:
contrib/udp2/
├── CMakeLists.txt # Main build configuration
├── Makefile # PostgreSQL-compatible Makefile
└── ic_common/
├── CMakeLists.txt # ic_common library build configuration
└── build/ # Build output directory
Build process:
ic_common dynamic library (libic_common.so)udp2 module (udp2.so), linking against the ic_common library./configure --enable-ic-udp2 [other options] make && make install
# Check if udp2.so is generated ls -la $GPHOME/lib/postgresql/udp2.so # Check if ic_common library is installed ls -la $GPHOME/lib/libic_common.so
# Set cluster to use UDP2 by default gpconfig -c gp_interconnect_type -v udp2 # Reload configuration gpstop -air
-- Check current interconnect type SHOW gp_interconnect_type;
UDP2 achieves decoupling between database kernel and communication library through standardized C interfaces:
// Core interface functions (ic_common/udp2/ic_udp2.h) extern ICChunkTransportState* UDP2_SetupUDP(ICSliceTable *sliceTable, SessionMotionLayerIPCParam *param); extern void UDP2_TeardownUDP(ICChunkTransportState *transportStates, bool hasErrors); // Data send/receive interfaces extern bool UDP2_SendData(ICChunkTransportState *transportStates, int16 motNodeID, int16 targetRoute, DataBlock *pblocks, int num, bool broadcast); extern void UDP2_RecvAny(ICChunkTransportState *transportStates, int16 motNodeID, int16 *srcRoute, GetDataLenInPacket getLen, DataBlock *data);
UDP2 defines lightweight data structures to replace complex database kernel structures:
// Lightweight process information (replaces CdbProcess) typedef struct ICCdbProcess { bool valid; char *listenerAddr; int listenerPort; int pid; int contentid; int dbid; } ICCdbProcess; // Lightweight slice information (replaces ExecSlice) typedef struct ICExecSlice { int sliceIndex; int parentIndex; int numChildren; int *children; int numSegments; int numPrimaryProcesses; ICCdbProcess *primaryProcesses; } ICExecSlice;
UDP2 implements a unified error handling mechanism:
typedef enum ErrorLevel { LEVEL_OK, LEVEL_ERROR, LEVEL_FATAL, } ErrorLevel; // Error handling interfaces extern void SetLastError(ErrorLevel level, const char *msg); extern ICError* GetLastError(); extern void ResetLastError();
# Enter ic_common directory cd contrib/udp2/ic_common # Create build directory mkdir build && cd build # Configure and compile cmake -DCMAKE_BUILD_TYPE=Debug .. make -j
Enable verbose logging in development environment:
-- Enable interconnect debug logging SET gp_log_interconnect = 'debug'; -- Set log level SET log_min_messages = 'debug1'; -- Enable detailed error information SET gp_interconnect_log_stats = on;