Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MySQL] Add connection attribute example for Go
See - Pull Request: go-sql-driver/mysql#1389 - Release: https://github.com/go-sql-driver/mysql/releases/tag/v1.8.0
- Loading branch information
1 parent
4f2b470
commit 8fba7d9
Showing
5 changed files
with
173 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
![MySQL logo](../../images/mysql-logo.png) | ||
|
||
# your _MySQL_ connection deserves a name: Go edition (with github.com/go-sql-driver/mysql) | ||
|
||
An example on how to assign a name to a [MySQL](https://www.mysql.com/) connection in Go. | ||
|
||
## Get it running | ||
|
||
1. Start the MySQL docker container: | ||
```sh | ||
$ docker run --rm \ | ||
--publish 3306:3306 \ | ||
--env MYSQL_ROOT_PASSWORD=secret \ | ||
--env MYSQL_DATABASE=dummy \ | ||
--name ycdan-mysql \ | ||
--detach \ | ||
mysql:8.0.36 mysqld --default-authentication-plugin=mysql_native_password | ||
``` | ||
|
||
2. Compile the example program: | ||
```sh | ||
$ go build -o your-connection-deserves-a-name | ||
``` | ||
|
||
3. Start the example program: | ||
```sh | ||
$ ./your-connection-deserves-a-name | ||
``` | ||
|
||
You should see something like | ||
|
||
``` | ||
2024/03/17 09:04:05 Connecting to MySQL on root:secret@tcp(127.0.0.1:3306)/dummy?connectionAttributes=program_name:currency-conversion-app | ||
2024/03/17 09:04:05 Connecting to MySQL on root:secret@tcp(127.0.0.1:3306)/dummy?connectionAttributes=program_name:currency-conversion-app ... Successful | ||
2024/03/17 09:04:05 | ||
2024/03/17 09:04:05 Keeping the connection open ... | ||
2024/03/17 09:04:05 You can connect to the MySQL database and execute the query: | ||
2024/03/17 09:04:05 SELECT | ||
2024/03/17 09:04:05 session_connect_attrs.ATTR_VALUE AS program_name, | ||
2024/03/17 09:04:05 processlist.* | ||
2024/03/17 09:04:05 FROM information_schema.processlist | ||
2024/03/17 09:04:05 LEFT JOIN performance_schema.session_connect_attrs ON ( | ||
2024/03/17 09:04:05 processlist.ID = session_connect_attrs.PROCESSLIST_ID | ||
2024/03/17 09:04:05 AND session_connect_attrs.ATTR_NAME = "program_name" | ||
2024/03/17 09:04:05 ) | ||
2024/03/17 09:04:05 Hit CTRL + C or cancel the process to stop. | ||
2024/03/17 09:04:05 | ||
``` | ||
|
||
4. Login into your database and execute the query: | ||
```sql | ||
SELECT | ||
session_connect_attrs.ATTR_VALUE AS program_name, | ||
processlist.* | ||
FROM information_schema.processlist | ||
LEFT JOIN performance_schema.session_connect_attrs ON ( | ||
processlist.ID = session_connect_attrs.PROCESSLIST_ID | ||
AND session_connect_attrs.ATTR_NAME = "program_name" | ||
) | ||
``` | ||
|
||
The result should look similar to: | ||
|
||
``` | ||
program_name | ID | USER | HOST | DB | [...] | ||
--------------------+----+------+------------------+-------+------ | ||
unit-conversion-app | 11 | root | 172.17.0.1:56382 | dummy | [...] | ||
``` | ||
|
||
## Don't know what this is all about? | ||
|
||
Read the original blog post [_your database connection deserves a name @ andygrunwald.com_](https://andygrunwald.com/blog/your-database-connection-deserves-a-name/ "Article your database connection deserves a name at Andy Grunwalds blog"). | ||
|
||
Additionally, you can check out the [projects README](https://github.com/andygrunwald/your-connection-deserves-a-name#readme). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module github.com/andygrunwald/your-connection-deserves-a-name/mysql/go | ||
|
||
go 1.22.1 | ||
|
||
require ( | ||
filippo.io/edwards25519 v1.1.0 // indirect | ||
github.com/go-sql-driver/mysql v1.8.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= | ||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= | ||
github.com/go-sql-driver/mysql v1.8.0 h1:UtktXaU2Nb64z/pLiGIxY4431SJ4/dR5cjMmlVHgnT4= | ||
github.com/go-sql-driver/mysql v1.8.0/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package main | ||
|
||
import ( | ||
"database/sql" | ||
"fmt" | ||
"log" | ||
"net/url" | ||
"time" | ||
|
||
_ "github.com/go-sql-driver/mysql" | ||
) | ||
|
||
const ( | ||
MySQLUsername = "root" | ||
MySQLPassword = "secret" | ||
MySQLHostname = "127.0.0.1" | ||
MySQLPort = 3306 | ||
MySQLDatabase = "dummy" | ||
ConnectionAttributeName = "program_name" | ||
ConnectionName = "currency-conversion-app" | ||
) | ||
|
||
func main() { | ||
// Doing all the magic: Setting a proper connection/application name. | ||
// | ||
// Connection attributes are key-value pairs that application programs can pass to the server at connect time. | ||
// This property can be added to the connection string. | ||
// | ||
// The application name will be maintained in the `session_connect_attrs` table of your MySQL-Server. | ||
// | ||
// MySQL docs: | ||
// - Performance Schema Connection Attribute Tables: https://dev.mysql.com/doc/refman/8.0/en/performance-schema-connection-attribute-tables.html | ||
// - Connection Attribute Limits: https://dev.mysql.com/doc/refman/8.0/en/performance-schema-connection-attribute-tables.html#performance-schema-connection-attribute-limits | ||
|
||
dsn := fmt.Sprintf("%s@tcp(%s:%d)/%s?connectionAttributes=%s:%s", url.UserPassword(MySQLUsername, MySQLPassword), MySQLHostname, MySQLPort, MySQLDatabase, ConnectionAttributeName, ConnectionName) | ||
|
||
// Building the connection | ||
log.Printf("Connecting to MySQL on %s\n", dsn) | ||
client, err := sql.Open("mysql", dsn) | ||
if err != nil { | ||
panic(err) | ||
} | ||
defer func() { | ||
if err = client.Close(); err != nil { | ||
panic(err) | ||
} | ||
}() | ||
|
||
// Dummy values for demo purpose | ||
client.SetConnMaxLifetime(time.Minute * 3) | ||
client.SetMaxOpenConns(10) | ||
client.SetMaxIdleConns(10) | ||
|
||
// Establish the connection, because depending on the DB driver, we might only | ||
// validate the credentials, but don't built up a connection. | ||
err = client.Ping() | ||
if err != nil { | ||
panic(err) | ||
} | ||
log.Printf("Connecting to MySQL on %s ... Successful\n", dsn) | ||
|
||
log.Println("") | ||
log.Println("Keeping the connection open ...") | ||
log.Println("You can connect to the MySQL database and execute the query:") | ||
log.Println(" SELECT") | ||
log.Println(" session_connect_attrs.ATTR_VALUE AS program_name,") | ||
log.Println(" processlist.*") | ||
log.Println(" FROM information_schema.processlist") | ||
log.Println(" LEFT JOIN performance_schema.session_connect_attrs ON (") | ||
log.Println(" processlist.ID = session_connect_attrs.PROCESSLIST_ID") | ||
log.Println(" AND session_connect_attrs.ATTR_NAME = \"program_name\"") | ||
log.Println(" )") | ||
log.Println("Hit CTRL + C or cancel the process to stop.") | ||
log.Println("") | ||
|
||
// Just looping to keep the process running. | ||
// In detail we do not keep the connection active, but rely on the standard timeout. | ||
// This way we provide time for the user to check the connection name behaviour. | ||
for { | ||
err = client.Ping() | ||
if err != nil { | ||
panic(err) | ||
} | ||
time.Sleep(5 * time.Second) | ||
} | ||
} |