Cant' connect to a MySQL database - mysql

I have a MySQL server on CentOS 7 and I want to try connecting a program written in Go to that database server. For the database server (MySQL) is work correctly and I tried to make one database and table.
+-----+------------+
| no | nama |
+-----+------------+
| 001 | Example |
+-----+------------+
MySQL username: golang
MySQL password: cobadatabase
CentOS 7 (MySQL Server) Machine's IP: 192.168.102.175:3306 (Default Port)
and My laptop's IP: 192.168.102.170
**. So, Database server exist on different machine (remotely).
Here is my Go code:
func main() {
/* Ini konekin database-nya dulu */
app_database, err := sql.Open("mysql", "golang:cobadatabase#tcp(192.168.102.175:3360)/example")
/* Nah klo ini Error Handling */
if err != nil {
log.Fatal(err) // informasi log jika koneksi database gagal
}
defer app_database.Close() // Close koneksi jika benar-benar gagal
/* End of Error Handling Connection */
var (
no string
nama string
)
baris, err := app_database.Query("SELECT * FROM example_table")
if err != nil {
log.Fatal(err)
}
defer baris.Close()
for baris.Next() {
err := baris.Scan(&no, &nama)
if err != nil {
log.Fatal(err)
}
log.Println(no, nama)
}
err = baris.Err()
if err != nil {
log.Fatal(err)
}
}
When I run my program, it fails with this error:
dial tcp 192.168.102.175:3360 connectex: A connection attempt failed because the connected party did not properly respond.

Related

How to connect MySQL with AWS?

I am trying to connect the MySQL database with AWS RDS but don't have any idea what should be included.
I created the RDS database, got the DB HOST value, and got the region but I don't know how to apply it and make it work.
func Connect() (db *sql.DB) {
db_user := middleware.LoadEnvVariable("DB_USER")
db_password := middleware.LoadEnvVariable("DB_PASSWORD")
db_address := middleware.LoadEnvVariable("DB_ADDRESS")
db_db := middleware.LoadEnvVariable("DB_DB")
s := fmt.Sprintf("%s:%s#tcp(%s:3306)/%s", db_user, db_password, db_address, db_db)
db, err := sql.Open("mysql", s)
if err != nil {
log.Fatal(err)
}
return db
}

How to connect to AWS RDS using Golang?

I am trying to connect to the AWS RDS using the following code. I got help from this website but when I executed this code, it gave me the following error.
Error
panic: failed to create authentication token: failed to refresh cached credentials, no EC2 IMDS role found, operation error ec2imds: GetMetadata, request canceled, context deadline exceeded
Code
func Connect() (db *sql.DB) {
db_user := middleware.LoadEnvVariable("DB_USER")
// db_password := middleware.LoadEnvVariable("DB_PASSWORD")
db_host := "database endpoint string"
db_db := middleware.LoadEnvVariable("DB_DB")
dbEndpoint := fmt.Sprintf("%s:%d", db_address, 3306)
region := "ap-south-1a"
cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
panic("configuration error: " + err.Error())
}
authenticationToken, err := auth.BuildAuthToken(context.TODO(), dbEndpoint, region, db_user, cfg.Credentials)
if err != nil {
panic("failed to create authentication token: " + err.Error())
}
s := fmt.Sprintf("%s:%s#tcp(%s)/%s?tls=true&allowCleartextPasswords=true", db_user, authenticationToken, dbEndpoint, db_db)
dbbase, err := sql.Open("mysql", s)
if err != nil {
log.Fatal(err)
}
return dbbase
}

Issue with connections pool on mysql

I'm having some issues with the api I'm developing: sometimes (yes, not always) when I make a request to the golang server from my angular app, it gaves me this error: "sql: database is closed" when I'm tring to execute "QueryContext", but I figured that it happens more frequently on a func that request a larger data from database (200 record top).
Is there a way to check if the connection is still open\valid? shouldn't golang's connection pool do it automatically? (I have other api more "light" in the same server with the same database and everything work smootly)
Is there any MySql setting I should change?(mysql has defaullt settings)
golang version: 1.16,
Mysql 8.0.17
Hre is an example of my code:
on package database.go
func OpenConnection() (*sql.DB, error)
{
connection, err = sql.Open("mysql", "root#/my_database")
if err != nil {
log.Println("Error opening the connection with the database")
return nil, err
}
return connection, nil
}
On main.go
func main() {
---
http.HandleFunc("/apicall1", customFunc)
http.HandleFunc("/apicall2", customFunc)
http.HandleFunc("/apicall3", customFunc)
}
func customFunc(w http.ResponseWriter, r *http.Request) {
conn, err := database.OpenConnection()
if err != nil {
//handle error 500 response
}
defer conn.Close()
switch(r.URL.Path) {
case "url1": my_package.Func1(conn)
case "url2": my_package.Func2(conn)
case "url3": my_package.Func3(conn)
...
default: //handle not found response
}
}
You need to configure your sql.DB for better performance from your pool and to avoid hitting max limit of your db allowed connection, here as an example I have made max 100 connection and idle 25 you can change it as per the load. Also it's a nice idea to ping db after making successful connection, just to ensure connection is success.
func OpenConnection() (*sql.DB, error)
{
connection, err = sql.Open("mysql", "root#/my_database")
if err != nil {
log.Println("Error opening the connection with the database")
return nil, err
}
connection.DB().SetMaxIdleConns(25)
connection.DB().SetMaxOpenConns(100)
dberr = connection.DB().Ping()
if dberr != nil {
log.Println("failed to ping db repository : %s", dberr)
return nil, dberr
}
return connection, nil
}
Reference - https://www.alexedwards.net/blog/configuring-sqldb

Error while creating connection with phpmyadmin using golang "commands out of sync. Did you run multiple statements at once?"

I'm facing some issue while fetching the data from the MySQL database using golang below is my code and the error that I'm facing
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func ConnectMsqlDb() (db *sql.DB, err error) {
db, err = sql.Open("mysql", fmt.Sprintf("%s:%s#tcp(%s:"+sqlDbPort+")/"+sqlDB, sqlUserName, sqlPassword, dbServerIP))
if err != nil {
return nil, err
}
//defer db.Close()
err = db.Ping()
if err != nil {
return nil, err
}
return db, nil
}
func GetSqlData() (err error, data interface{}) {
db, err := ConnectMsqlDb()
if err != nil {
// here it will returning me the error
return err, nil
}
rows, err := db.Query("SELECT * FROM users")
if err != nil {
return err, nil
}
for rows.Next() {
}
defer db.Close()
fmt.Println(rows)
return err, rows
}
func main() {
err, data := GetSqlData()
fmt.Println("data", data, "err", err)
}
error
data commands out of sync. Did you run multiple statements at once?
Can anyone tell me why I'm facing this issue
If the error is comming while opening a connection to mysqld , it could be possible that MySQL server (mysqld) is blocking the host from connecting to it. It means that mysqld has received many connection requests from the given host that were interrupted in the middle.
Read why? To confirm you could see the DB's logs as well. So, a way to unblock it is to flush the cached hosts using the MySQL CLI:
mysql> FLUSH HOSTS;
And then try again to connect.
Plus, give this answer a read as well. Might help.
You can check the state of the socket used by mysqld using (For Linux):
netstat -nt
Check if there's any previously hanging connection from the host to mysqld. If yes, then kill it and try again.

How to create a new MySQL database with go-sql-driver

I'm working on Golang script that automatically clone a database.
I'm using go-sql-driver but i can't find in the documentation a way to create a new database.
Connection to MySQL require an URL scheme like:
user:password#tcp(localhost:3306)/database_name
But the database not exists yet, I just want to connect to the server and then create a new one.
How can I do that? I have to use another driver?
You can perfectly use the go-sql-driver. However, you need to use a mysql user which has the proper access rights to create new databases.
Here is an example:
func create(name string) {
db, err := sql.Open("mysql", "admin:admin#tcp(127.0.0.1:3306)/")
if err != nil {
panic(err)
}
defer db.Close()
_,err = db.Exec("CREATE DATABASE "+name)
if err != nil {
panic(err)
}
_,err = db.Exec("USE "+name)
if err != nil {
panic(err)
}
_,err = db.Exec("CREATE TABLE example ( id integer, data varchar(32) )")
if err != nil {
panic(err)
}
}
Note that the database name is not provided in the connection string. We just create the database after the connection (CREATE DATABASE command), and switch the connection to use it (USE command).
Note: the VividCortex guys maintain a nice database/sql tutorial and documentation at http://go-database-sql.org/index.html
If you want to create a new database if it does not exist, and use it directly in your program, be aware that database/sql maintains a connection pool.
Therefore the opened database connection, should preferably contain the database name. I've seen "Error 1046: No database selected" when database/sql opens a new connection after using db.Exec("USE "+name) manually.
func createAndOpen(name string) *sql.DB {
db, err := sql.Open("mysql", "admin:admin#tcp(127.0.0.1:3306)/")
if err != nil {
panic(err)
}
defer db.Close()
_,err = db.Exec("CREATE DATABASE IF NOT EXISTS "+name)
if err != nil {
panic(err)
}
db.Close()
db, err = sql.Open("mysql", "admin:admin#tcp(127.0.0.1:3306)/" + name)
if err != nil {
panic(err)
}
defer db.Close()
return db
}
My db_config.go file looks like for GO ORM 2.0:
package infrastructure
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm2.0/utils"
)
//Setup Models: initializaing the mysql database
func GetDatabaseInstance() *gorm.DB {
get := utils.GetEnvWithKey
USER := get("DB_USER")
PASS := get("DB_PASS")
HOST := get("DB_HOST")
PORT := get("DB_PORT")
DBNAME := get("DB_NAME")
dsn := fmt.Sprintf("%s:%s#tcp(%s:%s)/%s?charset=utf8&parseTime=True&loc=Local", USER, PASS, HOST, PORT, DBNAME)
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
_ = db.Exec("CREATE DATABASE IF NOT EXISTS " + DBNAME + ";")
if err != nil {
panic(err.Error())
}
return db
}