У меня есть экземпляр PostgreSQL, работающий в Digital Ocean. При использовании инструмента командной строки psql я могу нормально подключиться к базе данных. Я использую следующую команду:
psql "host=db-postgresql-nyc1-70444-do-user-4921290-0.b.db.ondigitalocean.com port=25060 dbname=defaultdb user=doadmin password=MY_PASSWORD sslmode=require"
Теперь я скомпилировал исполняемый файл, который использует libpq
и libpqxx
. Я скомпилировал две библиотеки, используя следующие аргументы (как видите, поддерживается ssl).
# Unix like system
test -e postgresql-12.2.tar.gz || wget https://ftp.postgresql.org/pub/source/v12.2/postgresql-12.2.tar.gz
test -e postgresql-12.2 || tar -xzvf postgresql-12.2.tar.gz
cd postgresql-12.2
test -e build_amd64 && rm -rf build_amd64
mkdir build_amd64
cd build_amd64
../configure --without-readline CFLAGS = "-O3 -fpic" CXXFLAGS = "-fpic" CPPFLAGS = "-fpic" --prefix=$PWD/packaged --with-includes=$(pwd)/../../openssl-OpenSSL_1_1_1k/build_amd64/packaged/include/ --with-openssl --with-libraries=$(pwd)/../../openssl-OpenSSL_1_1_1k/build_amd64/packaged/lib/
# multithreaded make
if [ "$(uname)" == "Darwin" ]; then
sysctl -n hw.physicalcpu | xargs -I % make -j%
elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
nproc | xargs -I % make -j%
fi
make install
ar dv packaged/lib/libpq.a legacy-pqsignal.o
test -e 7.0.7.tar.gz || wget https://github.com/jtv/libpqxx/archive/7.0.7.tar.gz
test -e libpqxx-7.0.7 || tar -xzvf 7.0.7.tar.gz
cd libpqxx-7.0.7
test -e build_amd64 && rm -rf build_amd64
mkdir build_amd64
cd build_amd64
# Unix like system
LIBNAME=libpq.so
if [[ "$OSTYPE" == "darwin"* ]]; then
LIBNAME=libpq.dylib
fi
cmake -DPostgreSQL_TYPE_INCLUDE_DIR=${PWD}/../../postgresql-12.2/build_amd64/packaged/include \
-DPostgreSQL_LIBRARY=${PWD}/../../postgresql-12.2/build_amd64/packaged/lib/${LIBNAME} \
-DPostgreSQL_INCLUDE_DIR=${PWD}/../../postgresql-12.2/build_amd64/packaged/include \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON -D CMAKE_BUILD_TYPE=Release -DBUILD_TEST=OFF ..
# multithreaded make
if [ "$(uname)" == "Darwin" ]; then
sysctl -n hw.physicalcpu | xargs -I % make -j%
elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
nproc | xargs -I % make -j%
fi
make DESTDIR=./packaged install
# On centos, it is installed to lib64 instead of lib, so create a symbolic link for consistency
test -e packaged/usr/local/lib || ln -s ./lib64/ ./packaged/usr/local/lib
Затем я передаю точно такую же строку подключения конструктору pqxx::connection
следующим образом:
m_connectionPtr = std::make_unique<pqxx::connection>("host=db-postgresql-nyc1-70444-do-user-4921290-0.b.db.ondigitalocean.com port=25060 dbname=defaultdb user=doadmin password=MY_PASSWORD sslmode=require");
Однако при этом выдается следующее исключение:
terminate called after throwing an instance of 'pqxx::broken_connection'
what(): FATAL: pg_hba.conf rejects connection for host "181.224.248.206", user "doadmin", database "template1", SSL on
Aborted (core dumped)
Что бы это ни стоило, я могу подключиться к базе данных PostgreSQL, используя мою логику libpqxx
выше, когда она работает локально на том же компьютере. Я на всю жизнь не могу подключиться к удаленной базе данных, хотя и использую libpqxx
. Любые идеи?
Редактировать:
У меня нет доступа к pg_hba.conf
на сервере, так как это управляемая база данных, размещенная в Digital Ocean. Однако на странице консоли цифрового океана говорится, что база данных открыта для подключений со всех IP-адресов.
Редактировать 2
Теперь я понимаю проблему. В моем исполняемом файле я сначала подключался к базе данных template1
, а затем делал запрос к базе данных, чтобы узнать, существует ли имя базы данных, предоставленное пользователем (с libpqxx
вы можете делать запросы к базе данных только после того, как вы установили соединение с БД, и вам требуется имя базы данных для создания соединения). Этот подход не работал с размещенными службами баз данных, такими как Digital Ocean, поскольку они не позволяют вам подключаться к базе данных template1
. Как только я удалил эту логику из своего кода, я смог правильно подключиться напрямую к указанной базе данных.
О да! Я забыл, что ранее в своем коде я подключался к базе данных template1
, чтобы затем запросить базу данных и проверить, существует ли имя базы данных, предоставленное пользователем. У меня сложилось впечатление, что template1
существует для всех баз данных PostgreSQL, думаю, это не так! Спасибо незнакомец.
Я понимаю, в чем проблема:
В моем исполняемом файле я сначала подключался к базе данных template1
, а затем делал запрос к базе данных, чтобы узнать, существует ли имя базы данных, предоставленное пользователем (с libpqxx
вы можете делать запросы к базе данных только после того, как вы установили соединение с БД, и вам требуется имя базы данных для создания соединения). Этот подход не работал с размещенными службами баз данных, такими как Digital Ocean, поскольку они не позволяют вам подключаться к базе данных template1
. Как только я удалил эту логику из своего кода, я смог правильно подключиться напрямую к указанной базе данных.
Ваша строка подключения говорит, что она подключается к defaultdb, но в сообщении об ошибке говорится, что она пытается подключиться к template1. Таким образом, в имени базы данных явно есть некоторая несоответствие.