はじめに
RedshiftにCLIで接続する際、PostgreSQLのCLIであるpsqlを使用することが多いと思いますが、最新のpsqlだと特定のメタコマンドが使用できないことがあります
Ubuntu 24.04LTSの標準のPostgreSQLは17であるため、17のpostgresql-clientでは以下のようなエラーとなります
dev => \l
ERROR: column d.datcollate does not exist
dev => \d tablename
ERROR: column c.relhastriggers does not exis
個人的には\l
はあまり使うことはないですが、\d
が使えないのはなかなかツライところです
これはRedshiftのベースとなるPostgreSQLのバージョンが古いことによるもので、psqlで接続した際に出力されるメッセージから
psql (17.2 (Ubuntu 17.2-1.pgdg24.04+1), server 8.0.2)
WARNING: psql major version 17, server major version 8.0.
Some psql features might not work.
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, compression: off, ALPN: none)
Type "help" for help.
とPostgreSQL 8ベースであり「一部動かないかもね」って警告メッセージがでます
弊社環境としてRedshift以外にAurora PostgreSQLもあるため、PostgreSQL ClientをRedshiftに合わせるというのも難しい状況です
そこで両方使えるよう、Redshiftに依存しないよう考えたいと思います
個人的には思いつく選択肢として
- Redshift RSQL
- PostgreSQL Clientを複数バージョン入れる
でしょうか
Redshift RSQL
Redshift RSQLはAWSが提供しているCLIツールです
LinuxではRPMでしか提供されておらず、2023年6月19日が現時点での最新バージョンとなってます
rpmをdebパッケージ化にするのに alien コマンドが使えますが、まずは使えるのかを検証してみます
Redshift用のODBCドライバとRSQLをダウンロードします
wget https://s3.amazonaws.com/redshift-downloads/drivers/odbc/2.1.6.0/AmazonRedshiftODBC-64-bit-2.1.6.0.x86_64.rpm
wget https://s3.amazonaws.com/redshift-downloads/amazon-redshift-rsql/1.0.8/AmazonRedshiftRsql-1.0.8.x86_64.rpm
rpmの中身を見るためにrpm2cpioをインストールします
$ sudo apt install rpm2cpio
rpmからファイルを抜き出します
$ rpm2cpio AmazonRedshiftODBC-64-bit-2.1.6.0.x86_64.rpm | cpio --list
./opt/amazon/redshiftodbcx64/amazon.redshiftodbc.ini
./opt/amazon/redshiftodbcx64/librsodbc64.so
./opt/amazon/redshiftodbcx64/odbc.csh
./opt/amazon/redshiftodbcx64/odbc.ini
./opt/amazon/redshiftodbcx64/odbc.sh
./opt/amazon/redshiftodbcx64/odbcinst.ini
./opt/amazon/redshiftodbcx64/root.crt
./opt/amazon/redshiftodbcx64/rsodbcsql
./opt/amazon/redshiftodbcx64/samples/connect/connect
./opt/amazon/redshiftodbcx64/samples/connect/connect.c
./opt/amazon/redshiftodbcx64/samples/connect/connect.mak
277765 blocks
$ rpm2cpio AmazonRedshiftODBC-64-bit-2.1.6.0.x86_64.rpm | cpio -id
277765 blocks
$ rpm2cpio AmazonRedshiftRsql-1.0.8.x86_64.rpm | cpio --list
./usr/share/aws/rsql/bin/rsql
./usr/share/aws/rsql/lib/libpq.so
./usr/share/aws/rsql/lib/libpq.so.5
./usr/share/aws/rsql/lib/libpq.so.5.1
./usr/share/aws/rsql/readme.txt
2389 blocks
$ rpm2cpio AmazonRedshiftRsql-1.0.8.x86_64.rpm | cpio -id
2389 blocks
実行ファイルとライブラリが使用するライブラリを確認してみます
$ ldd librsodbc64.so
linux-vdso.so.1 (0x00007ffcd6fca000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f0afac1c000)
libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f0afac09000)
libkeyutils.so.1 => /lib/x86_64-linux-gnu/libkeyutils.so.1 (0x00007f0afac02000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f0afabfd000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f0afabf8000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0af9717000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0af9505000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0afac29000)
$ ldd rsodbcsql
linux-vdso.so.1 (0x00007ffe6c1fe000)
libodbc.so.2 => /lib/x86_64-linux-gnu/libodbc.so.2 (0x00007fecd47c9000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fecd454b000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fecd4462000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fecd4434000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fecd4222000)
libltdl.so.7 => /lib/x86_64-linux-gnu/libltdl.so.7 (0x00007fecd4215000)
/lib64/ld-linux-x86-64.so.2 (0x00007fecd4841000)
$ ldd rsql
linux-vdso.so.1 (0x00007ffdbfb98000)
libodbc.so.2 => /lib/x86_64-linux-gnu/libodbc.so.2 (0x00007f0d4c7ae000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f0d4c7a9000)
libssl.so.10 => not found
libcrypto.so.10 => not found
libreadline.so.6 => not found
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f0d4c7a2000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0d4c6b9000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0d4c4a7000)
libltdl.so.7 => /lib/x86_64-linux-gnu/libltdl.so.7 (0x00007f0d4c49c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0d4c826000)
$ ldd libpq.so.5.1
linux-vdso.so.1 (0x00007ffdd3907000)
libssl.so.1.1 => not found
libcrypto.so.1.1 => not found
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fd4ee365000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd4ee153000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd4ee3bf000)
ODBCドライバはぱっと見では大丈夫そうですが、RSQLパッケージ側がOpenSSLとreadlineのライブラリがないようです
$ ldconfig -p | grep libssl.so
libssl.so.3 (libc6,x86-64) => /lib/x86_64-linux-gnu/libssl.so.3
libssl.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libssl.so
$ ldconfig -p | grep libcrypto.so
libcrypto.so.3 (libc6,x86-64) => /lib/x86_64-linux-gnu/libcrypto.so.3
libcrypto.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libcrypto.so
$ ldconfig -p | grep libreadline.so
libreadline.so.8 (libc6,x86-64) => /lib/x86_64-linux-gnu/libreadline.so.8
libreadline.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libreadline.so
not foundとなっている3つともUbuntu 24.04LTSよりバージョンが古いものを必要としています
特に、OpenSSLは1.0系と1.1系が必要そうですが、1.0系・1.1系はすでにEOLとなってます
また、libpq.soはPostgreSQLのライブラリですが、Ubuntu 24.04LTSのバージョンと比較するとこれもかなり古いです
$ ldconfig -p | grep libpq.so
libpq.so.5 (libc6,x86-64) => /lib/x86_64-linux-gnu/libpq.so.5
$ ls -l /lib/x86_64-linux-gnu/libpq.so.5*
lrwxrwxrwx 1 root root 13 Nov 19 23:36 /lib/x86_64-linux-gnu/libpq.so.5 -> libpq.so.5.17
-rw-r--r-- 1 root root 354496 Nov 19 23:36 /lib/x86_64-linux-gnu/libpq.so.5.17
現時点で1年半もリリースがされておらず、OpenSSLものEOLのバージョンのままのでRSQLを使用するのは微妙なのでこちらは断念します
PostgreSQL Clientを複数バージョン入れる
Ubuntuのpsqlコマンドは pg_wrapper というPerlスクリプトのsymlinkとなっており、このスクリプトが複数バージョンを切り替えて使用できるようになっています
(pg_wrapperはpostgresql-client-commonに含まれています)
実際のPostgreSQL Clientは /usr/lib/postgresql/{version}
下にインストールされてます
$ which psql
/usr/bin/psql
$ ls -l /usr/bin/psql
lrwxrwxrwx 1 root root 37 Aug 9 11:33 /usr/bin/psql -> ../share/postgresql-common/pg_wrapper*
$ file /usr/share/postgresql-common/pg_wrapper
/usr/share/postgresql-common/pg_wrapper: Perl script text executable
PostgreSQL Clientを複数バージョンインストールできるようにレポジトリを追加します
$ sudo apt install -y postgresql-common
$ sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
$ apt list postgresql-client*
Listing... Done
postgresql-client-10-dbgsym/noble-pgdg 10.23-7.pgdg24.04+1 amd64
postgresql-client-10/noble-pgdg 10.23-7.pgdg24.04+1 amd64
postgresql-client-11-dbgsym/noble-pgdg 11.22-9.pgdg24.04+1 amd64
postgresql-client-11/noble-pgdg 11.22-9.pgdg24.04+1 amd64
postgresql-client-12-dbgsym/noble-pgdg 12.22-2.pgdg24.04+1 amd64
postgresql-client-12/noble-pgdg 12.22-2.pgdg24.04+1 amd64
postgresql-client-13-dbgsym/noble-pgdg 13.18-1.pgdg24.04+1 amd64
postgresql-client-13/noble-pgdg 13.18-1.pgdg24.04+1 amd64
postgresql-client-14-dbgsym/noble-pgdg 14.15-1.pgdg24.04+1 amd64
postgresql-client-14/noble-pgdg,now 14.15-1.pgdg24.04+1 amd64
postgresql-client-15-dbgsym/noble-pgdg 15.10-1.pgdg24.04+1 amd64
postgresql-client-15/noble-pgdg,now 15.10-1.pgdg24.04+1 amd64
postgresql-client-16-dbgsym/noble-pgdg 16.6-1.pgdg24.04+1 amd64
postgresql-client-16/noble-pgdg 16.6-1.pgdg24.04+1 amd64
postgresql-client-17-dbgsym/noble-pgdg 17.2-1.pgdg24.04+1 amd64
postgresql-client-17/noble-pgdg,now 17.2-1.pgdg24.04+1 amd64 [installed,automatic]
postgresql-client-8.2/noble-pgdg 8.2.23-13.pgdg24.04+1 amd64
postgresql-client-8.3/noble-pgdg 8.3.23-10.pgdg24.04+1 amd64
postgresql-client-8.4/noble-pgdg 8.4.22-11.pgdg24.04+1 amd64
postgresql-client-9.0/noble-pgdg 9.0.23-11.pgdg24.04+1 amd64
postgresql-client-9.1/noble-pgdg 9.1.24-17.pgdg24.04+1 amd64
postgresql-client-9.2/noble-pgdg 9.2.24-14.pgdg24.04+1 amd64
postgresql-client-9.3/noble-pgdg 9.3.25-13.pgdg24.04+1 amd64
postgresql-client-9.4/noble-pgdg 9.4.26-13.pgdg24.04+1 amd64
postgresql-client-9.5/noble-pgdg 9.5.25-11.pgdg24.04+1 amd64
postgresql-client-9.6/noble-pgdg 9.6.24-10.pgdg24.04+1 amd64
postgresql-client-common/noble-pgdg,now 267.pgdg24.04+1 all [installed,automatic]
postgresql-client/noble-pgdg,now 17+267.pgdg24.04+1 all [installed]
RedshiftがPostgreSQL 8.0ベースなので postgresql-client-8.2
をインストールしてもいいのですが、postgresql-client-14 でもエラーとなっていたメタコマンドが正常に動作したので 14 をインストールします
$ sudo apt install -y postgresql-client-14
ただし、pg_wrapperの128~136行目の以下の箇所でpsqlはインストール済の最新バージョンを使用するようになっており、psqlでは常に最新バージョンを使うようになっています
# if we have no version yet, use the latest version. If we were called as psql,
# pg_archivecleanup, or pg_isready, always use latest version
if (not $version or $cmdname =~ /^(psql|pg_archivecleanup|pg_isready)$/) {
my $max_version;
if ($version and $version < 9.2) { # psql 15 only supports PG 9.2+
$max_version = 14;
}
$version = get_newest_version($cmdname, $max_version);
}
今回、psqlでAWS上のRedshiftとAuroraにしか使用しないため、psqlでもバージョン切り替えができるようにpg_wrapperを変更します
postgresql-client-commonをUpdateすると元に戻ってしまうため、このスクリプトをHomeディレクトリ化にコピーします
$ mkdir $HOME/bin
$ cp /usr/share/postgresql-common/pg_wrapper $HOME/bin
コピーしたpg_wrapperを以下のように修正します
--- /usr/share/postgresql-common/pg_wrapper 2024-11-21 19:54:02.000000000 +0900
+++ bin/pg_wrapper 2025-02-06 15:04:20.478248118 +0900
@@ -127,7 +127,7 @@
# if we have no version yet, use the latest version. If we were called as psql,
# pg_archivecleanup, or pg_isready, always use latest version
-if (not $version or $cmdname =~ /^(psql|pg_archivecleanup|pg_isready)$/) {
+if (not $version or $cmdname =~ /^(pg_archivecleanup|pg_isready)$/) {
my $max_version;
if ($version and $version < 9.2) { # psql 15 only supports PG 9.2+
$max_version = 14
修正後、psqlのsymlinkを作成し $HOME/bin
を先に参照するように環境変数 PATH に追加します
$ cd $HOME/bin
$ ln -sf pg_wrapper psql
$ export PATH=$HOME/bin:$PATH
pg_wrapperでのバージョンを切り替えての使用は以下となるので
$ psql --client {version}/{host}:{port} -U {username} {database}
Redshiftへの接続の場合は以下となります
$ psql --client 14/redshift:5439 -U awsuser dev
psql (14.15 (Ubuntu 14.15-1.pgdg24.04+1), server 8.0.2)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
Aurora PostgreSQLの15バージョンでは以下で接続できます
$ psql --client 15/aurora:5432 -U postgres postgres
psql (15.10 (Ubuntu 15.10-1.pgdg24.04+1), server 15.4)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.
-h
で指定した場合は最新の 17 のものが使用されます
$ psql -h aurora -p 5432 -U postgres postgres
psql (17.2 (Ubuntu 17.2-1.pgdg24.04+1), server 15.4)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off, ALPN: none)
Type "help" for help.
psqlコマンドで --client
を指定するのはあまり慣れていないですが、やりたいことは達成できました