-
Notifications
You must be signed in to change notification settings - Fork 124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SNOW-1346547: Error when using async queries: "390112: Your session has expired. Please login again." #1119
Comments
hi and thanks for raising this and the hints too! I'll take a look and see if i can reproduce. |
trying to reproduce the issue, so far with no success. Using the following approach with go1.21 and gosnowflake 1.9.0..
So implemented a 5-minute session policy instead of the 4-hour to speed up tests. Now my authentication token is only valid for 5m. CREATE SESSION POLICY test_db.public.session_policy_5m
SESSION_IDLE_TIMEOUT_MINS = 5
SESSION_UI_IDLE_TIMEOUT_MINS = 5
COMMENT = 'Session policy 5m'
;
ALTER ACCOUNT SET SESSION POLICY test_db.public.session_policy_5m;
package main
import (
"context"
"database/sql"
"fmt"
"log"
"time"
"strconv"
sf "github.com/snowflakedb/gosnowflake"
)
func main() {
connectionString := "username:password@myorg-myaccount/test_db/public?warehouse=COMPUTE_WH&role=ACCOUNTADMIN&tracing=TRACE&CLIENT_SESSION_KEEP_ALIVE=true&CLIENT_SESSION_KEEP_ALIVE_HEARTBEAT_FREQUENCY=3600" // default heartbeat is 3600 (1h) anyways
noCachedResults := "ALTER SESSION SET USE_CACHED_RESULT = FALSE;"
selectQuery := "SELECT * FROM SNOWFLAKE_SAMPLE_DATA.TPCH_SF1000.PARTSUPP;" // 800M rows, 35.1GB data
sleepSeconds := 290
db, err := sql.Open("snowflake", connectionString)
if err != nil {
log.Fatal(err)
}
defer db.Close()
// enable async mode
ctx := sf.WithAsyncMode(context.Background())
conn, err := db.Conn(ctx)
if err != nil {
log.Fatalf("Failed to acquire connection. err: %v", err)
}
defer conn.Close()
_, err = conn.ExecContext(ctx, noCachedResults)
if err != nil {
log.Fatalf("failed to execute ALTER SESSION. err: %v", err)
}
// sleep for a little less than 5 minutes (300s)
// Session idle policy is set to 5 minutes in this test
fmt.Println("Sleeping " + strconv.Itoa(sleepSeconds) + " seconds.")
time.Sleep(time.Duration(sleepSeconds) * time.Second)
// now run the big query in an async manner
// this query surely should take more than 5 minutes on a x-small warehouse
rows, err := conn.QueryContext(ctx, selectQuery)
if err != nil {
// 'handle' error
fmt.Println(err)
}
defer rows.Close()
var counter int
var v1, v2, v3, v4, v5 sql.NullString
for rows.Next() {
err = rows.Scan(&v1, &v2, &v3, &v4, &v5)
if err != nil {
log.Fatalf("failed to get result. err: %v", err)
}
// not really interested in query result, but still want it executed fully
counter++
}
if rows.Err() != nil {
fmt.Printf("ERROR: %v\n", rows.Err())
return
}
fmt.Println(counter)
} The query takes around 8.5 minutes on a x-small warehouse to execute. Here's what happens:
Never encountered So at this point I'm a little baffled how to get to the issue and therefore to troubleshoot further, it would be really appreciated if you could please send a minimal viable reproduction program, which when run, would exhibit the issue you're having. As a mitigation, you can perhaps consider adding Thank you in advance for the reproducible example ! |
Here's a reproduction of the issue, which has up to this point been illusive to me. It has to run for 1 hour in order for the error to occur, seemingly regardless of what the session idle timeout is set to in the session policy. The 2 hour func main() {
connectionString := "redacted"
db, err := sql.Open("snowflake", connectionString)
if err != nil {
log.Fatal(err)
}
defer db.Close()
ctx := context.Background()
if err := db.PingContext(ctx); err != nil {
log.Fatal(err)
}
res, err := db.ExecContext(sf.WithAsyncMode(ctx), "CALL SYSTEM$WAIT(2, 'HOURS');")
if err != nil {
log.Fatal(err)
}
if _, err := res.RowsAffected(); err != nil {
log.Fatal(err)
}
} |
thank you for the hint and the repro - I'm taking a look. |
looks like you were right; 1 hour is indeed relevant - because it looks like the heartbeat itself which is breaking things and the heartbeat happens after one hour. We'll fix this and I'll update this thread on the progress as any new information becomes available. |
fix PR under review at #1160 |
fix PR is merged and will be part of the next release |
released with gosnowflake v1.11.0 in July 2024 |
Please answer these questions before submitting your issue.
In order to accurately debug the issue this information is required. Thanks!
What version of GO driver are you using?
1.9.0
What operating system and processor architecture are you using?
darwin/arm64
What version of GO are you using?
go version go1.22.0 darwin/arm64
4.Server version:* E.g. 1.90.1
8.16.0
client_session_keep_alive
set totrue
.The program continue to run. Instead, it will occasionally crash with an error
"390112: Your session has expired. Please login again."
In the driver code, I see here where sessions should be getting renewed. From what I can see, an async query will later end up in this loop. I'm wondering if a session is still valid on that first check but just about to expire, and the session ends up expired in the retry loop without being gracefully handled? This would race with the session renewal heartbeat process that is enabled with
client_session_keep_alive
.Not easily - this is currently being worked-around by always creating a new client when a batch of async queries need to be run. My guess is that this gets a "fresh" session each time, instead of letting the prior session expire.
The text was updated successfully, but these errors were encountered: