Monday, April 24, 2017

MySQL CLI mode localhost ignoring --PORT option

I have a issue like this in the past, either in Java or PHP, but never dug into the details of how MySQL server treats its command-line options for Localhost connection.

Basically, Localhost would point to local machine and implicitly means local IP like 127.0.0.1.

For standard MySQL instance, port number is default to 3306. To connect MySQL on different port number is possible by changing port number directly. However, such behaviour is a little bit different on Localhost connection.

Even MariaDB shares common bugs/features with its variant MySQL.

When connecting to MySQL instance on Localhost, you can type the followings with success:
> mysql -uuser -p -hlocalhost -P3306
> mysql -uuser -p -hlocalhost -P3307
> mysql -uuser -p -hlocalhost -P80
> mysql -uuser -p -hlocalhost -P443

They will absolutely redirect you to the instance Localhost:3306. I think of this a bug, yet someone has got an explanation on the official site for years:

On Unix, MySQL programs treat the host name localhost specially, in a way that is likely different from what you expect compared to other network-based programs. For connections to localhost, MySQL programs attempt to connect to the local server by using a Unix socket file. This occurs even if a --port or -P option is given to specify a port number. To ensure that the client makes a TCP/IP connection to the local server, use --host or -h to specify a host name value of 127.0.0.1, or the IP address or name of the local server. You can also specify the connection protocol explicitly, even for localhost, by using the --protocol=TCP option.
MySQL is based on Unix development source so behaviour will follow even when it's complied to Windows release.

To reach one particular port number on Localhost, we must specify the actual IP address. This ensures MySQL connection is done through TCP protocol rather than socket file.

In other words,
> mysql -uuser -p -hlocalhost -P3306 --protocol=TCP
> mysql -uuser -p -hlocalhost -P3307 --protocol=TCP
> mysql -uuser -p -hlocalhost -P80 --protocol=TCP
> mysql -uuser -p -hlocalhost -P443 --protocol=TCP
> mysql -uuser -p -h127.0.0.1 -P3306
> mysql -uuser -p -h127.0.0.1 -P3307
> mysql -uuser -p -h127.0.0.1 -P80
> mysql -uuser -p -h127.0.0.1 -P443

This will make sure we connect to Localhost on the port number as specified.

Ref: https://dev.mysql.com/doc/refman/5.7/en/connecting.html