@@ -47,8 +47,7 @@ public ServerSession(ILogger logger, IConnectionPoolMetadata pool)
4747 public int ActiveCommandId { get ; private set ; }
4848 public int CancellationTimeout { get ; private set ; }
4949 public int ConnectionId { get ; set ; }
50- public string ? ServerUuid { get ; set ; }
51- public long ? ServerId { get ; set ; }
50+ public string ? ServerHostname { get ; set ; }
5251 public byte [ ] ? AuthPluginData { get ; set ; }
5352 public long CreatedTimestamp { get ; }
5453 public ConnectionPool ? Pool { get ; }
@@ -121,11 +120,21 @@ public void DoCancel(ICancellableCommand commandToCancel, MySqlCommand killComma
121120
122121 // Verify server identity before executing KILL QUERY to prevent cancelling on the wrong server
123122 var killSession = killCommand . Connection ! . Session ;
124- if ( ! VerifyServerIdentity ( killSession ) )
123+ if ( ! string . IsNullOrEmpty ( ServerHostname ) && ! string . IsNullOrEmpty ( killSession . ServerHostname ) )
125124 {
126- Log . IgnoringCancellationForDifferentServer ( m_logger , Id , killSession . Id , ServerUuid , killSession . ServerUuid , ServerId , killSession . ServerId ) ;
125+ if ( ! string . Equals ( ServerHostname , killSession . ServerHostname , StringComparison . Ordinal ) )
126+ {
127+ Log . IgnoringCancellationForDifferentServer ( m_logger , Id , killSession . Id , ServerHostname , killSession . ServerHostname ) ;
128+ return ;
129+ }
130+ }
131+ else if ( ! string . IsNullOrEmpty ( ServerHostname ) || ! string . IsNullOrEmpty ( killSession . ServerHostname ) )
132+ {
133+ // One session has hostname, the other doesn't - this is a potential mismatch
134+ Log . IgnoringCancellationForDifferentServer ( m_logger , Id , killSession . Id , ServerHostname , killSession . ServerHostname ) ;
127135 return ;
128136 }
137+ // If both sessions have no hostname, allow the operation for backward compatibility
129138
130139 // NOTE: This command is executed while holding the lock to prevent race conditions during asynchronous cancellation.
131140 // For example, if the lock weren't held, the current command could finish and the other thread could set ActiveCommandId
@@ -147,26 +156,6 @@ public void AbortCancel(ICancellableCommand command)
147156 }
148157 }
149158
150- private bool VerifyServerIdentity ( ServerSession otherSession )
151- {
152- // If server UUID is available, use it as the primary identifier (most unique)
153- if ( ! string . IsNullOrEmpty ( ServerUuid ) && ! string . IsNullOrEmpty ( otherSession . ServerUuid ) )
154- {
155- return string . Equals ( ServerUuid , otherSession . ServerUuid , StringComparison . Ordinal ) ;
156- }
157-
158- // Fall back to server ID if UUID is not available
159- if ( ServerId . HasValue && otherSession . ServerId . HasValue )
160- {
161- return ServerId . Value == otherSession . ServerId . Value ;
162- }
163-
164- // If no server identification is available, allow the operation to proceed
165- // This maintains backward compatibility with older MySQL versions
166- Log . NoServerIdentificationForVerification ( m_logger , Id , otherSession . Id ) ;
167- return true ;
168- }
169-
170159 public bool IsCancelingQuery => m_state == State . CancelingQuery ;
171160
172161 public async Task PrepareAsync ( IMySqlCommand command , IOBehavior ioBehavior , CancellationToken cancellationToken )
@@ -665,8 +654,8 @@ public async Task DisposeAsync(IOBehavior ioBehavior, CancellationToken cancella
665654 ConnectionId = newConnectionId ;
666655 }
667656
668- // Get server identification for KILL QUERY verification
669- await GetServerIdentificationAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
657+ // Get server hostname for KILL QUERY verification
658+ await GetServerHostnameAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
670659
671660 m_payloadHandler . ByteHandler . RemainingTimeout = Constants . InfiniteTimeout ;
672661 return redirectionUrl ;
@@ -1984,76 +1973,36 @@ private async Task GetRealServerDetailsAsync(IOBehavior ioBehavior, Cancellation
19841973 }
19851974 }
19861975
1987- private async Task GetServerIdentificationAsync ( IOBehavior ioBehavior , CancellationToken cancellationToken )
1976+ private async Task GetServerHostnameAsync ( IOBehavior ioBehavior , CancellationToken cancellationToken )
19881977 {
1989- Log . GettingServerIdentification ( m_logger , Id ) ;
1978+ Log . GettingServerHostname ( m_logger , Id ) ;
19901979 try
19911980 {
1992- PayloadData payload ;
1993-
1994- // Try to get both server_uuid and server_id if server supports server_uuid (MySQL 5.6+)
1995- if ( ! ServerVersion . IsMariaDb && ServerVersion . Version >= ServerVersions . SupportsServerUuid )
1996- {
1997- payload = SupportsQueryAttributes ? s_selectServerIdWithAttributesPayload : s_selectServerIdNoAttributesPayload ;
1998- await SendAsync ( payload , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
1999-
2000- // column count: 2
2001- _ = await ReceiveReplyAsync ( ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
1981+ var payload = SupportsQueryAttributes ? s_selectHostnameWithAttributesPayload : s_selectHostnameNoAttributesPayload ;
1982+ await SendAsync ( payload , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
20021983
2003- // @@server_uuid and @@server_id columns
2004- _ = await ReceiveReplyAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
2005- _ = await ReceiveReplyAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
1984+ // column count: 1
1985+ _ = await ReceiveReplyAsync ( ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
20061986
2007- if ( ! SupportsDeprecateEof )
2008- {
2009- payload = await ReceiveReplyAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
2010- _ = EofPayload . Create ( payload . Span ) ;
2011- }
1987+ // @@hostname column
1988+ _ = await ReceiveReplyAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
20121989
2013- // first (and only) row
1990+ if ( ! SupportsDeprecateEof )
1991+ {
20141992 payload = await ReceiveReplyAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
2015-
2016- var reader = new ByteArrayReader ( payload . Span ) ;
2017- var length = reader . ReadLengthEncodedIntegerOrNull ( ) ;
2018- var serverUuid = length > 0 ? Encoding . UTF8 . GetString ( reader . ReadByteString ( length ) ) : null ;
2019- length = reader . ReadLengthEncodedIntegerOrNull ( ) ;
2020- var serverId = ( length > 0 && Utf8Parser . TryParse ( reader . ReadByteString ( length ) , out long id , out _ ) ) ? id : default ( long ? ) ;
2021-
2022- ServerUuid = serverUuid ;
2023- ServerId = serverId ;
2024-
2025- Log . RetrievedServerIdentification ( m_logger , Id , serverUuid , serverId ) ;
1993+ _ = EofPayload . Create ( payload . Span ) ;
20261994 }
2027- else
2028- {
2029- // Fall back to just server_id for older versions or MariaDB
2030- payload = SupportsQueryAttributes ? s_selectServerIdOnlyWithAttributesPayload : s_selectServerIdOnlyNoAttributesPayload ;
2031- await SendAsync ( payload , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
2032-
2033- // column count: 1
2034- _ = await ReceiveReplyAsync ( ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
2035-
2036- // @@server_id column
2037- _ = await ReceiveReplyAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
20381995
2039- if ( ! SupportsDeprecateEof )
2040- {
2041- payload = await ReceiveReplyAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
2042- _ = EofPayload . Create ( payload . Span ) ;
2043- }
2044-
2045- // first (and only) row
2046- payload = await ReceiveReplyAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
1996+ // first (and only) row
1997+ payload = await ReceiveReplyAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
20471998
2048- var reader = new ByteArrayReader ( payload . Span ) ;
2049- var length = reader . ReadLengthEncodedIntegerOrNull ( ) ;
2050- var serverId = ( length > 0 && Utf8Parser . TryParse ( reader . ReadByteString ( length ) , out long id , out _ ) ) ? id : default ( long ? ) ;
1999+ var reader = new ByteArrayReader ( payload . Span ) ;
2000+ var length = reader . ReadLengthEncodedIntegerOrNull ( ) ;
2001+ var hostname = length > 0 ? Encoding . UTF8 . GetString ( reader . ReadByteString ( length ) ) : null ;
20512002
2052- ServerUuid = null ;
2053- ServerId = serverId ;
2003+ ServerHostname = hostname ;
20542004
2055- Log . RetrievedServerIdentification ( m_logger , Id , null , serverId ) ;
2056- }
2005+ Log . RetrievedServerHostname ( m_logger , Id , hostname ) ;
20572006
20582007 // OK/EOF payload
20592008 payload = await ReceiveReplyAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
@@ -2064,10 +2013,9 @@ private async Task GetServerIdentificationAsync(IOBehavior ioBehavior, Cancellat
20642013 }
20652014 catch ( MySqlException ex )
20662015 {
2067- Log . FailedToGetServerIdentification ( m_logger , ex , Id ) ;
2068- // Set fallback values to ensure operation can continue
2069- ServerUuid = null ;
2070- ServerId = null ;
2016+ Log . FailedToGetServerHostname ( m_logger , ex , Id ) ;
2017+ // Set fallback value to ensure operation can continue
2018+ ServerHostname = null ;
20712019 }
20722020 }
20732021
@@ -2302,10 +2250,8 @@ protected override void OnStatementBegin(int index)
23022250 private static readonly PayloadData s_sleepWithAttributesPayload = QueryPayload . Create ( true , "SELECT SLEEP(0) INTO @__MySqlConnector__Sleep;"u8 ) ;
23032251 private static readonly PayloadData s_selectConnectionIdVersionNoAttributesPayload = QueryPayload . Create ( false , "SELECT CONNECTION_ID(), VERSION();"u8 ) ;
23042252 private static readonly PayloadData s_selectConnectionIdVersionWithAttributesPayload = QueryPayload . Create ( true , "SELECT CONNECTION_ID(), VERSION();"u8 ) ;
2305- private static readonly PayloadData s_selectServerIdNoAttributesPayload = QueryPayload . Create ( false , "SELECT @@server_uuid, @@server_id;"u8 ) ;
2306- private static readonly PayloadData s_selectServerIdWithAttributesPayload = QueryPayload . Create ( true , "SELECT @@server_uuid, @@server_id;"u8 ) ;
2307- private static readonly PayloadData s_selectServerIdOnlyNoAttributesPayload = QueryPayload . Create ( false , "SELECT @@server_id;"u8 ) ;
2308- private static readonly PayloadData s_selectServerIdOnlyWithAttributesPayload = QueryPayload . Create ( true , "SELECT @@server_id;"u8 ) ;
2253+ private static readonly PayloadData s_selectHostnameNoAttributesPayload = QueryPayload . Create ( false , "SELECT @@hostname;"u8 ) ;
2254+ private static readonly PayloadData s_selectHostnameWithAttributesPayload = QueryPayload . Create ( true , "SELECT @@hostname;"u8 ) ;
23092255
23102256 private readonly ILogger m_logger ;
23112257#if NET9_0_OR_GREATER
0 commit comments