Skip to content

Conversation

@dveeden
Copy link
Collaborator

@dveeden dveeden commented Dec 8, 2025

This work was triggered by this: #1067 (comment)

Tested with:

mysql-8.4.7 [(none)]> SHOW GLOBAL VARIABLES LIKE 'session\_track\_%';
+--------------------------------+------------------------------------------------------------------------------------------+
| Variable_name                  | Value                                                                                    |
+--------------------------------+------------------------------------------------------------------------------------------+
| session_track_gtids            | ALL_GTIDS                                                                                |
| session_track_schema           | ON                                                                                       |
| session_track_state_change     | ON                                                                                       |
| session_track_system_variables | time_zone,autocommit,character_set_client,character_set_results,character_set_connection |
| session_track_transaction_info | CHARACTERISTICS                                                                          |
+--------------------------------+------------------------------------------------------------------------------------------+
5 rows in set (0.002 sec)
package main

import (
	"fmt"

	"github.com/go-mysql-org/go-mysql/client"
	"github.com/go-mysql-org/go-mysql/mysql"
)

func main() {
	conn, err := client.Connect("127.0.0.1:3306", "root", "", "", func(conn *client.Conn) error {
		conn.SetCapability(mysql.CLIENT_SESSION_TRACK)
		return nil
	})
	if err != nil {
		panic(err)
	}
	defer conn.Quit()

	res, _ := conn.Execute("SELECT VERSION() AS ver")
	version, _ := res.GetStringByName(0, "ver")
	res.Close()
	fmt.Println(version)

	res, err = conn.UseDBWithResult("mysql")
	fmt.Printf("session tracking: %#v\n", res.SessionTracking)
	res.Close()

	res, _ = conn.Execute("SET SESSION autocommit=0")
	fmt.Printf("session tracking: %#v\n", res.SessionTracking)
	res.Close()

	res, _ = conn.Execute("SET SESSION autocommit=1")
	fmt.Printf("session tracking: %#v\n", res.SessionTracking)
	res.Close()

	res, _ = conn.Execute("START TRANSACTION READ ONLY")
	fmt.Printf("session tracking: %#v\n", res.SessionTracking)
	res.Close()

	res, _ = conn.Execute("START TRANSACTION READ WRITE")
	fmt.Printf("session tracking: %#v\n", res.SessionTracking)
	res.Close()

	res, _ = conn.Execute("ROLLBACK")
	fmt.Printf("session tracking: %#v\n", res.SessionTracking)
	res.Close()

	res, err = conn.Execute("CREATE SCHEMA test")
	if err == nil {
		fmt.Printf("session tracking: %#v\n", res.SessionTracking)
		res.Close()
	}

	res, _ = conn.UseDBWithResult("test")
	fmt.Printf("session tracking: %#v\n", res.SessionTracking)

	res, _ = conn.Execute("CREATE TABLE IF NOT EXISTS t(id int primary key)")
	fmt.Printf("session tracking: %#v\n", res.SessionTracking)
	res.Close()

	res, _ = conn.Execute("DELETE FROM t")
	fmt.Printf("session tracking: %#v\n", res.SessionTracking)
	res.Close()

	res, _ = conn.Execute("INSERT INTO t VALUES (1),(2),(3)")
	fmt.Printf("StatusMessage: %s\n", res.StatusMessage)
	fmt.Printf("session tracking: %#v\n", res.SessionTracking)
	res.Close()

	res, _ = conn.Execute("SET GTID_NEXT='AUTOMATIC:xmas'")
	fmt.Printf("session tracking: %#v\n", res.SessionTracking)
	res.Close()

	res, _ = conn.Execute("INSERT INTO t VALUES (4),(5),(6)")
	fmt.Printf("session tracking: %#v\n", res.SessionTracking)
	res.Close()

	res, _ = conn.Execute("SET @a := 12345")
	fmt.Printf("session tracking: %#v\n", res.SessionTracking)
	res.Close()
}

Output:

8.4.7
session tracking: &mysql.SessionTrackingInfo{GTID:"", TransactionState:"", Variables:map[string]string(nil), Schema:"mysql", State:"1", Characteristics:""}
session tracking: &mysql.SessionTrackingInfo{GTID:"f4993c5e-d353-11f0-9b5f-eede6d5626c8:1-279:xmas:1-30", TransactionState:"", Variables:map[string]string{"autocommit":"OFF"}, Schema:"", State:"1", Characteristics:""}
session tracking: &mysql.SessionTrackingInfo{GTID:"f4993c5e-d353-11f0-9b5f-eede6d5626c8:1-279:xmas:1-30", TransactionState:"", Variables:map[string]string{"autocommit":"ON"}, Schema:"", State:"1", Characteristics:""}
session tracking: &mysql.SessionTrackingInfo{GTID:"", TransactionState:"T_______", Variables:map[string]string(nil), Schema:"", State:"", Characteristics:"START TRANSACTION READ ONLY;"}
session tracking: &mysql.SessionTrackingInfo{GTID:"", TransactionState:"", Variables:map[string]string(nil), Schema:"", State:"", Characteristics:"START TRANSACTION READ WRITE;"}
session tracking: &mysql.SessionTrackingInfo{GTID:"", TransactionState:"________", Variables:map[string]string(nil), Schema:"", State:"", Characteristics:""}
session tracking: &mysql.SessionTrackingInfo{GTID:"", TransactionState:"", Variables:map[string]string(nil), Schema:"test", State:"1", Characteristics:""}
session tracking: &mysql.SessionTrackingInfo{GTID:"f4993c5e-d353-11f0-9b5f-eede6d5626c8:1-280:xmas:1-30", TransactionState:"", Variables:map[string]string(nil), Schema:"", State:"", Characteristics:""}
session tracking: &mysql.SessionTrackingInfo{GTID:"f4993c5e-d353-11f0-9b5f-eede6d5626c8:1-281:xmas:1-30", TransactionState:"", Variables:map[string]string(nil), Schema:"", State:"", Characteristics:""}
StatusMessage: Records: 3  Duplicates: 0  Warnings: 0
session tracking: &mysql.SessionTrackingInfo{GTID:"f4993c5e-d353-11f0-9b5f-eede6d5626c8:1-282:xmas:1-30", TransactionState:"", Variables:map[string]string(nil), Schema:"", State:"", Characteristics:""}
session tracking: &mysql.SessionTrackingInfo{GTID:"f4993c5e-d353-11f0-9b5f-eede6d5626c8:1-282:xmas:1-30", TransactionState:"", Variables:map[string]string(nil), Schema:"", State:"1", Characteristics:""}
session tracking: &mysql.SessionTrackingInfo{GTID:"f4993c5e-d353-11f0-9b5f-eede6d5626c8:1-282:xmas:1-31", TransactionState:"", Variables:map[string]string(nil), Schema:"", State:"", Characteristics:""}
session tracking: &mysql.SessionTrackingInfo{GTID:"f4993c5e-d353-11f0-9b5f-eede6d5626c8:1-282:xmas:1-31", TransactionState:"", Variables:map[string]string(nil), Schema:"", State:"1", Characteristics:""}

@dveeden dveeden requested a review from lance6716 December 8, 2025 18:38
@dveeden
Copy link
Collaborator Author

dveeden commented Dec 8, 2025

We could automatically change c.db when there is a SESSION_TRACK_SCHEMA, but I don't think we should.

One of the possible usecases is this:

  1. Write to a primary, Use session tracking to get the OWN_GTID.
  2. Read from a replica with WAIT_FOR_EXECUTED_GTID_SET().

This gives a way to improve the read-after-write experience without having to always read from the primary.

@lance6716
Copy link
Collaborator

I need some time to learn https://dev.mysql.com/doc/refman/8.4/en/session-state-tracking.html

@dveeden
Copy link
Collaborator Author

dveeden commented Dec 9, 2025

Another implementation method could be a per connection channel with the session tracking info

@lance6716 lance6716 merged commit 0d3c2e3 into go-mysql-org:master Dec 10, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants