[MDEV-14974] --port ignored for --host=localhost Created: 2018-01-17  Updated: 2023-08-30  Resolved: 2021-05-12

Status: Closed
Project: MariaDB Server
Component/s: Scripts & Clients
Affects Version/s: 5.5, 10.0, 10.1, 10.2
Fix Version/s: 10.6.1

Type: Bug Priority: Major
Reporter: Martin Häcker Assignee: Brandon Nesterenko
Resolution: Fixed Votes: 2
Labels: beginner-friendly

Issue Links:
Relates
relates to MDEV-28850 mysql client program conflicting prot... Open
Sub-Tasks:
Key
Summary
Type
Status
Assignee
MDEV-25723 Review Knowledgebase Documentation Ed... Technical task Closed Ian Gilfillan  

 Description   

mysql as well as mysqldump (and presumedly all the other tools) silently ignore the --port option if no host is given or it is localhost.

This happens because localhost is treaded specially, and instead a socket connection is made. So the problem here, is that giving --port does not force --protocol=tcp, which would fix this problem.

There are several things that are wrong with this:

a) it is not described with the --port option in the man pages of the respective tools
b) a user input is silently discarded, not even a warning is printed
c) This is really surprising.
d) It is documented somewhere, but not in the obvious places
e) There is already a bug report on this in oracles bug tracker since ages https://bugs.mysql.com/bug.php?id=55796

Well, I'm running out of steam coming up with more letter reasons. But this behavior is really annoying. When would I as the user want to have an explicit `--port` argument be ignored if I give it? I mean, if mysql where able to deduce somehow that the port is going to the same mysql instance as the socket it can find - fine - but I would be very surprised if it could without connecting to both.



 Comments   
Comment by Elena Stepanova [ 2018-01-23 ]

greenman,
Regarding d), it's documented in MariaDB KB in a reasonable place: mysql Command-line Client – but maybe it makes sense to somehow link port, host and protocol description to this section? Also, regarding a), if it's missing in man pages, it needs to be added. Can you do it or should it be somebody else?

However, I quite agree with the request in principle, I also find it redundant, annoying and prone to human errors that one has to specify protocol in addition to port; I myself had numerous occasions when things would go wrong because it was forgotten.

Unfortunately e), the fact that it was rejected for MySQL, actually makes things more difficult, it would be an unwanted difference in client behavior.

Still, I'll leave it to serg to decide if we can change it.

Comment by Martin Häcker [ 2018-01-24 ]

I would like to suggest that if you decide not to change it (for compatibility with mysql) then you should at least print a warning to stderr that it is ignored and how to fix that.

Comment by Sergei Golubchik [ 2018-01-28 ]

It won't be too difficult to assume protocol=tcp or at least issue a warning if the port is specified on the command line.
But I think if the port is specified in a config file, it should work as before.

It's doable, but do we want this? An option on the command-line treated differently from the option in a config file?

Comment by Martin Häcker [ 2018-01-30 ]

If you are giving a warning if `--port` is specified on the command line, you should also give it if port is specified in the config. I think this should be the minimum courtesy you give users.

I would advocate to also officially deprecate (as part of the warning) the behavior that port is ignored if set (anywhere).

I would think that it is reasonable not to ignore explicit options and honor them immediately, but you might want to have a deprecation period before you do that because giving your many users a chance to fix their config (I don't know what your normal deprecation period is, probably 1-2 years) could be advisable.

Comment by Martin Häcker [ 2018-03-22 ]

Any update here? Are you planning to do this? Is this something you would take a pull request for? Is this hard, where would that need to start? Are you planning to do that yourselves?

I'd appreciate some update. Thanks an advance!

Comment by Sergei Golubchik [ 2018-03-22 ]

No update. Yes, as long as it's not closed, we're planning to do it. Yes, we can take a pull request for anything, it depends on the pull request itself. It is not hard (that's why it has a label "beginner-friendly"). Yes, we're planning to do it ourselves, we don't expect a pull request to come. But it might take some time until we actually get to it.

More thoughts. If --port will always work, even in the config file, then there must be a way to "un-set" the port. Say, if the port is specified in /etc/my.cnf, but you want to use the socket. You wouldn't like if system-wide setting would force you to use tcp and you wouldn't have any way to override it. Perhaps, an explicit --protocol=socket ?

Comment by Martin Häcker [ 2018-03-23 ]

Thanks for the update - at least now it is clear what you guys are planning and what you would be willing to take as a pull request.

Cheers!

Comment by Martin Häcker [ 2018-12-04 ]

Weeeeeee!

Comment by Brandon Nesterenko [ 2021-04-26 ]

Hi!

I just wanted to share my plan for this fix for potential additional input:

1) Where there are multiple clients/frontends that can explicitly set port/protocol, my intention is to make this fix in the libmariadb (mariadb_lib.c) module to impact them all (excluding for replication purposes). More specifically, the plan is to override the values within the st_mysql/st_mysql_options types.

2) For testing/validation, I will add an MTR test (as well as a new command in client/mysqltest.cc for describing connection options) for the following cases:

Test Case 1) Only specify protocol with value as socket

Explicit parameters:
protocol=socket

Desired output:
Connection uses socket

Test Case 2) Only specify port

Explicit parameters:
port=$PORT

Desired output:
Connection uses TCP due to implication from specifying port
A warning message that notifies users of the changed behavior and that protocol=tcp should be explicitly specified together with port

Test Case 3) Specify both protocol with value as TCP and port

Explicit parameters:
protocol=tcp
port=$PORT

Desired output:
Connection uses TCP

Test Case 4) Specify both protocol with value as socket and port

Explicit parameters:
protocol=socket
port=$PORT

Desired output:
Connection uses socket due to prioritizing explicit protocol
A warning message that notifies users of the changed behavior and that protocol/port combination are inconsistent

Question: The above desired output assumes that the protocol option is always prioritized if explicitly passed. Would it make sense to use a different prioritization scheme? E.g. Choosing a latter option? sergElkin

3) Update relevant documentation in:

Comment by Vladislav Vaintroub [ 2021-04-27 ]

bnestere Keep in mind, that this bug is not a bug on Windows-. Socket is not a default protocol on Windows, in fact protocol=socket does not even exist (yet), the default protocol here has been TCP since eternity , "localhost" does not have any magic meanings here, and hence--port is not ignored for host=localhost.

Comment by Sergei Golubchik [ 2021-04-28 ]

bnestere:

  1. command line option handling is done in every client separately, so this should be done in mysql.cc (and may be in other clients from client/*c too)
  2. no need to add a new command to mysqltest language. First, there is a command already to describe connection options, and second this is an issue about command line option handling, not about any other way of specifying connection options. I suspect that you will only need mysqltest exec command, that's all. Like --exec $MYSQL --port=...
  3. yes, please
Comment by Brandon Nesterenko [ 2021-04-28 ]

That makes things much clearer, thanks for the comment! I do have a follow up question though regarding MTR. The My::ConfigFactory, which generates the default test config, outputs a port without a protocol in var/my.cnf. What is the intended behavior here for the connection protocol? Currently, it will default to socket. After addressing this, should the connection be implicitly changed to TCP or should it continue to be socket? serg Elkin

Comment by Sergei Golubchik [ 2021-04-28 ]

No, it shouldn't, see the third comment from the top, --port should only force protocol=tcp if specified on the command line.

Similarly, I think, --socket on the command line should force the protocol=socket.

Comment by Andrei Elkin [ 2021-05-04 ]

serg:

on the command line

includes the configuration file, correct?

Comment by Sergei Golubchik [ 2021-05-04 ]

No, it doesn't.

Comment by Andrei Elkin [ 2021-05-04 ]

serg: to the No, I am really puzzled.

I have thought an option in a configuration file is different from the same option on the command line only for the timing of their parsing.
E.g --port can be specified in 3 locations (and each have a number of option repeats) as in

mysql --defaults-file=file_def --defaults-extra-file=file_extra --port=effective_value

and the effective_value would prevail.

If it's correct so far, what makes the command line version of the option so special?

Comment by Andrei Elkin [ 2021-05-04 ]

Actually there's a 4th location aka the built-in default (to be "parsed" the first).

Comment by Sergei Golubchik [ 2021-05-05 ]

Command line version of the option is special, because it's what user sees and types. The old behavior is perfectly logical and correct and doesn't need any changes from that point of view. On the contrary, when one option magically modifies some other option value — this is usually confusing and illogical and rarely works well.

What we're doing here is increasing user friendliness for inexperienced users. Such a user types

mysql --port=3456

and expects mysql to actually use this port. A setting from the config file doesn't match this use case, if you write a config file, you could (and should) as well put the protocol=tcp there.

Yes, unfortunately this fix breaks the existing simple and clear logic of option handling and makes --port on the command line special. We don't do it lightly, but this is one of the very common sources of confusions indeed. So, probably, deserves the exception.

Comment by Andrei Elkin [ 2021-05-05 ]

serg, bnestere: All right, I realize now the backward compatibility concern! Would it make sense to planning the command-line exception into
a general rule with warnings when then the configuration-file options clash? E.g my.cnf [client]'s lonely port = 3456 (no --protocol) would start warning with the patch to override the socket default protocol in 10.7 with tcp as the warning would say.

Comment by Martin Häcker [ 2023-04-29 ]

Interesting that this bug report just cropped up again in my inbox, just when I was bitten by this bug again last week.

This case had a ~/.mycnf file, that specified `host=localhost`, but I tried connecting with a command-line that specified `--protocol=socket --socket=/some/path` - yet the socket and protocol was ignored, and again the connection was made to a different host. I had to add `--host=` to explicitly declare undeclare the host to get rid of this problematic behavior.

I really do think that you need to document the interdependency of these options and how they lead to ignore later command line arguments. I also think that it would be far more logical to have later options actually overwrite earlier options, especially if they are given through another means (in this case `.mycnf` vs command line).

Here is what I would have expect:

  • host specified in .mycnf, `--protocol=socket --socket=$path` - that declaration should win, no warning generated
  • host, protocol, socket specified all on the command line - a warning is warranted, last option should still win.

What do you think and why?

Generated at Thu Feb 08 08:17:44 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.