11package session
22
33import (
4+ "database/sql"
45 "fmt"
56 "strconv"
67 "strings"
@@ -187,6 +188,35 @@ func (c *Context) IsLowerCaseTableName() bool {
187188 return lowerCaseTableNames != "0"
188189}
189190
191+ // GetMySQLVersion 获取MySQL版本号
192+ func (c * Context ) GetMySQLVersion () string {
193+ version , err := c .GetSystemVariable (SysVarVersion )
194+ if err != nil {
195+ log .NewEntry ().Errorf ("fail to load system variable version, error: %v" , err )
196+ return ""
197+ }
198+ return version
199+ }
200+
201+ // GetMySQLMajorVersion 获取MySQL主版本号
202+ func (c * Context ) GetMySQLMajorVersion () (int , error ) {
203+ versionStr := c .GetMySQLVersion ()
204+ if versionStr == "" {
205+ return 0 , fmt .Errorf ("unable to get MySQL version" )
206+ }
207+
208+ // 解析版本号,例如 "8.0.33" -> 8
209+ versionParts := strings .Split (versionStr , "." )
210+ if len (versionParts ) > 0 {
211+ majorVersion , err := strconv .Atoi (versionParts [0 ])
212+ if err == nil {
213+ return majorVersion , nil
214+ }
215+ }
216+
217+ return 0 , fmt .Errorf ("unable to parse MySQL version: %s" , versionStr )
218+ }
219+
190220func (c * Context ) getSchema (schemaName string ) (* SchemaInfo , bool ) {
191221 if c .IsLowerCaseTableName () {
192222 schemaName = strings .ToLower (schemaName )
@@ -478,6 +508,7 @@ func (c *Context) IsTableExist(stmt *ast.TableName) (bool, error) {
478508
479509const (
480510 SysVarLowerCaseTableNames = "lower_case_table_names"
511+ SysVarVersion = "version"
481512)
482513
483514// GetSystemVariable get system variable.
@@ -567,27 +598,31 @@ func (c *Context) GetCreateTableStmt(stmt *ast.TableName) (*ast.CreateTableStmt,
567598/*
568599建表语句可能如下:
569600CREATE TABLE `__all_server_event_history` (
570- `gmt_create` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
571- `svr_ip` varchar(46) NOT NULL,
572- `svr_port` bigint(20) NOT NULL,
573- `module` varchar(64) NOT NULL,
574- `event` varchar(64) NOT NULL,
575- `name1` varchar(256) DEFAULT '',
576- `value1` varchar(256) DEFAULT '',
577- `name2` varchar(256) DEFAULT '',
578- `value2` longtext DEFAULT NULL,
579- `name3` varchar(256) DEFAULT '',
580- `value3` varchar(256) DEFAULT '',
581- `name4` varchar(256) DEFAULT '',
582- `value4` varchar(256) DEFAULT '',
583- `name5` varchar(256) DEFAULT '',
584- `value5` varchar(256) DEFAULT '',
585- `name6` varchar(256) DEFAULT '',
586- `value6` varchar(256) DEFAULT '',
587- `extra_info` varchar(512) DEFAULT '',
588- PRIMARY KEY (`gmt_create`, `svr_ip`, `svr_port`)
601+
602+ `gmt_create` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
603+ `svr_ip` varchar(46) NOT NULL,
604+ `svr_port` bigint(20) NOT NULL,
605+ `module` varchar(64) NOT NULL,
606+ `event` varchar(64) NOT NULL,
607+ `name1` varchar(256) DEFAULT '',
608+ `value1` varchar(256) DEFAULT '',
609+ `name2` varchar(256) DEFAULT '',
610+ `value2` longtext DEFAULT NULL,
611+ `name3` varchar(256) DEFAULT '',
612+ `value3` varchar(256) DEFAULT '',
613+ `name4` varchar(256) DEFAULT '',
614+ `value4` varchar(256) DEFAULT '',
615+ `name5` varchar(256) DEFAULT '',
616+ `value5` varchar(256) DEFAULT '',
617+ `name6` varchar(256) DEFAULT '',
618+ `value6` varchar(256) DEFAULT '',
619+ `extra_info` varchar(512) DEFAULT '',
620+ PRIMARY KEY (`gmt_create`, `svr_ip`, `svr_port`)
621+
589622) DEFAULT CHARSET = utf8mb4 ROW_FORMAT = COMPACT COMPRESSION = 'none' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 10 TABLEGROUP = 'oceanbase'
590- partition by key_v2(svr_ip, svr_port)
623+
624+ partition by key_v2(svr_ip, svr_port)
625+
591626(partition p0,
592627partition p1,
593628partition p2,
@@ -606,7 +641,6 @@ partition p14,
606641partition p15)
607642
608643建表语句后半段是options,oceanbase mysql模式下的show create table结果返回的options中包含mysql不支持的options, 为了能解析, 方法将会倒着遍历建表语句, 每次找到右括号时截断后面的部分, 然后尝试解析一次, 直到解析成功, 此时剩余的建表语句将不在包含OB特有options
609-
610644*/
611645func (c * Context ) parseCreateTableSqlCompatibly (createTableSql string ) (* ast.CreateTableStmt , error ) {
612646 for i := len (createTableSql ) - 1 ; i >= 0 ; i -- {
@@ -889,3 +923,65 @@ func (c *Context) GetColumnCardinality(tn *ast.TableName, columnName string) (in
889923func (c * Context ) GetExecutor () * executor.Executor {
890924 return c .e
891925}
926+
927+ func (c * Context ) CheckTransactionNotCommittedMySQL5 (execSecs int ) (int , int , error ) {
928+ var count , timeoutCount int
929+ query := `SELECT COUNT(*) FROM information_schema.innodb_trx`
930+ results , err := c .GetExecutor ().Db .Query (query )
931+ if err != nil {
932+ return 0 , 0 , err
933+ }
934+ if len (results ) > 0 && len (results [0 ]) > 0 {
935+ countStr := results [0 ]["COUNT(*)" ]
936+ count , err = strconv .Atoi (countStr .String )
937+ if err != nil {
938+ return 0 , 0 , err
939+ }
940+ }
941+
942+ query = `SELECT COUNT(*) FROM information_schema.innodb_trx WHERE TIMESTAMPDIFF(SECOND, trx_started, NOW()) > ?`
943+ results , err = c .GetExecutor ().Db .Query (query , execSecs )
944+ if err != nil {
945+ return 0 , 0 , err
946+ }
947+ if len (results ) > 0 && len (results [0 ]) > 0 {
948+ countStr := results [0 ]["COUNT(*)" ]
949+ timeoutCount , err = strconv .Atoi (countStr .String )
950+ if err != nil {
951+ return 0 , 0 , err
952+ }
953+ }
954+
955+ return count , timeoutCount , nil
956+
957+ }
958+
959+ func (c * Context ) CheckTableRelatedTransactionNotCommittedMySQL8 (schema , table string ) (int , error ) {
960+ if schema == "" {
961+ return 0 , nil
962+ }
963+
964+ var results []map [string ]sql.NullString
965+ var err error
966+
967+ if table == "" {
968+ query := `SELECT COUNT(*) FROM performance_schema.data_locks WHERE object_schema = ?`
969+ results , err = c .GetExecutor ().Db .Query (query , schema )
970+ } else {
971+ query := `SELECT COUNT(*) FROM performance_schema.data_locks WHERE object_schema = ? AND object_name = ?`
972+ results , err = c .GetExecutor ().Db .Query (query , schema , table )
973+ }
974+
975+ if err != nil {
976+ return 0 , err
977+ }
978+
979+ if len (results ) > 0 && len (results [0 ]) > 0 {
980+ countStr := results [0 ]["COUNT(*)" ]
981+ if countStr .Valid {
982+ return strconv .Atoi (countStr .String )
983+ }
984+ }
985+
986+ return 0 , nil
987+ }
0 commit comments