Not compatible with MySQL 8.0
px3303 opened this issue · comments
MySQL 8.0 has introduced cache to improve the efficiency of information_schema queries, so it may lead to a consequence that users could not get the latest and accurate statistics when querying information_schema.
If using MySQL 8.0 as storage layer, trillian codes, without setting the session variable information_schema_stats_expiry
(the default is 86400 seconds), could not pass the TestMySQLRateLimiting
and TestQuotaManager_GetTokens_InformationSchema
.
--- FAIL: TestMySQLRateLimiting (1.13s)
quota_test.go:100: Test MySQL available at "root@tcp(127.0.0.1)/"
quota_test.go:124: timed out before rate limiting kicked in
FAIL
FAIL github.com/google/trillian/integration/quota 8.509s
--- FAIL: TestQuotaManager_GetTokens_InformationSchema (1.44s)
mysql_quota_test.go:118: Test MySQL available at "root@tcp(127.0.0.1)/"
--- FAIL: TestQuotaManager_GetTokens_InformationSchema/useSelectCount_=_false (1.34s)
mysql_quota_test.go:170: timed out
FAIL
FAIL github.com/google/trillian/quota/mysqlqm 4.407s
The countFromInformationSchema function in the codes depends on information_schema to return the latest statistics,
countFromInformationSchemaQuery = `
SELECT table_rows
FROM information_schema.tables
WHERE table_schema = schema()
AND table_name = ?
AND table_type = ?`
func countFromInformationSchema(ctx context.Context, db *sql.DB) (int, error) {
// information_schema.tables doesn't have an explicit PK, so let's play it safe and ensure
// the cursor returns a single row.
rows, err := db.QueryContext(ctx, countFromInformationSchemaQuery, "Unsequenced", "BASE TABLE")
if err != nil {
return 0, err
}
defer rows.Close()
if !rows.Next() {
return 0, errors.New("cursor has no rows after information_schema query")
}
var count int
if err := rows.Scan(&count); err != nil {
return 0, err
}
if rows.Next() {
return 0, errors.New("too many rows returned from information_schema query")
}
return count, nil
}
so anything that relies on this function may fail to work as normal.