Hello esteemed colleagues
I’ve spent about a day trying to figure this out but im getting nowhere
how to ping postgreSQL using Golang just to check that they can talk to each other
This works:
`henry@vhost1:~/Eos$ pg_isready -h localhost -p 5432 -U eos_user -d eos_db
localhost:5432 - accepting connections
Can also read and write to it via command line:
henry@vhost1:~/Eos$ sudo -u eos_user psql -d eos_db -c "SELECT * FROM logs;"
sudo -u eos_user psql -d eos_db -c "INSERT INTO logs (level, message) VALUES ('INFO', 'Test log entry');"
id | timestamp | level | message
----+----------------------------+-------+----------------
1 | 2024-12-22 14:21:41.265223 | INFO | Test log entry
2 | 2024-12-22 14:24:09.661304 | INFO | Test log entry
(2 rows)
INSERT 0 1
henry@vhost1:~/Eos$ sudo -u eos_user psql -d eos_db -c "SELECT * FROM logs;"
id | timestamp | level | message
----+----------------------------+-------+----------------
1 | 2024-12-22 14:21:41.265223 | INFO | Test log entry
2 | 2024-12-22 14:24:09.661304 | INFO | Test log entry
3 | 2024-12-22 17:09:57.48363 | INFO | Test log entry
(3 rows)
But it just refuses to work in Golang:
henry@vhost1:~/Eos$ sudo -u eos_user go run testDbPing.go
2024/12/22 17:05:09 Database is not ready: pq: password authentication failed for user "eos_user"
exit status 1
Here is the programme I’m using to try figure this out:
`package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/lib/pq"
)
func main() {
// Connection details
host := "localhost"
port := "5432"
user := "eos_user"
dbname := "eos_db"
// Connection string (no password for peer authentication)
connStr := fmt.Sprintf("host=%s port=%s user=%s dbname=%s sslmode=disable", host, port, user, dbname)
// Open a connection to the database
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatalf("Failed to open database connection: %v", err)
}
defer db.Close()
// Ping the database to check readiness
if err := db.Ping(); err != nil {
log.Fatalf("Database is not ready: %v", err)
}
fmt.Println("Database is ready!")
}`
Merry xmas and a happy new year
I’ve had a look here:
https://hevodata.com/learn/golang-postgres/#c2
and maybe im missing somehting but i just cant get it to work and ChatGPT insists it is correct.
2
Answers
Here's an update
This was the answer "Use a unix socket to connect in your go program. Using host := "/var/run/postgresql/" should work"
Here is the script I ended up using which worked:
And here is the terminal output
Cheers
Your two test commands are using different login methods and secondly,
pg_ready
does not care if a login fails, only that it could connect to the server to attempt a login.With your
psql
command you are logging in using a unix domain socket. This login method allows postgres to use the OS to authenticate the user of process that opened the connection. In this login method, no password or other authentication is needed. The OS has already verified that the process has permission to run as the given user.With
pg_ready
you are logging in using an inet socket over the loopback interface (localhost). Here postgres cannot use the OS to authenticate the identity of the user. As such is must use a different authentication method. As seen in yourgo
program, it appears to be using password-based authentication when connecting over localhost. However,pg_ready
does not care if a login is successful or not. Indeed, if the server responds that the login failed, then it stands to reason that the server is ready and accepting connections.If you try adding
-h localhost
to yourpsql
command you will find that it similarly fails.You need to either:
/var/lib/postgresql/data/pg_hba.conf
and refer to https://www.postgresql.org/docs/current/auth-pg-hba-conf.html for what it all means.host := "/var/run/postgresql/"
should work