Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add protocol = "tcp" as argument to dbConnect() #180

Open
matteodelucchi opened this issue Oct 8, 2020 · 13 comments
Open

Add protocol = "tcp" as argument to dbConnect() #180

matteodelucchi opened this issue Oct 8, 2020 · 13 comments

Comments

@matteodelucchi
Copy link

Situation

I host a mysql DB in a local docker container.

docker-compose.yml

version: '3.2'

services:
    db:
        image: mysql:8.0
        command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
        volumes:
            - ./mysql-dockerDB/var/lib/mysql:/var/lib/mysql
            - ./dockermnt:/docker-entrypoint-initdb.d
        container_name: mysqlDB
        restart: always
        ports:
            - '6603:3306'
        environment:
            MYSQL_ROOT_PASSWORD: secret

I expose the port 6603 to the localhost which allows me to access mysql in the container by i.e.:
mysql --host=localhost --port=6603 --user=root --password=secret --protocol=tcp

Problem

When I try to connect my local R Studio (not in docker) to mysqlDB via the open port with

con <- dbConnect(RMariaDB::MariaDB(),
                  dbname = "dbname",
                  username = "root",
                  password = "secret",
                  port = 6603)

I get the error: Error: Failed to connect: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2) . The same error happens when I specify host = "localhost" explicitly.
Which is unexpected, as I don't want to connect to the socket file rather using the TCP network protocol.
Unfortunately the argument protocol = "TCP" is not supported.

Workaround

I could solve the issue with specifying the protocol in the configuration file:

.my.cnf

[destination]
  port=6603
  proto=TCP

and then in R specifying the path to the configuration file and groups argument.

con <- dbConnect(RMariaDB::MariaDB(),
                  dbname = "dbname",
                  username = "root",
                  password = "secret",
                  groups="destination",
                  default.file = "<path-to-configuration-file>/.my.cnf")

Proposed Solution

In regard of the raising popularity of container stacks, it would be very valuable to have an argument in the method dbConnect() to directly specify the protocol type. Then, the workaround with the config file would be obsolete.
I imagine sth like this

con <- dbConnect(RMariaDB::MariaDB(),
                  dbname = "dbname",
                  username = "root",
                  password = "secret",
                  port = 6603,
                  protocol = "tcp")
@krlmlr
Copy link
Member

krlmlr commented Oct 18, 2020

Thanks. Does it work if you set host = "127.0.0.1" ?

I wonder if we should switch to TCP when a port argument has been provided.

@matteodelucchi
Copy link
Author

In that case, I get this error:
Can't read dir of '/etc/mysql/mariadb.conf.d/' (OS errno 2 - No such file or directory) [ERROR] Fatal error in defaults handling. Program aborted!

The directory actually would exist and contains the file mysqld.cnf, but I want to access the mysql in my docker container and not the local installation. I'm not an expert, but I think the path /etc/mysql/mariadb.conf.d/mysqld.cnf leads to a config file of my local installation and not the one in the docker container (didn't mount it to the docker as volume).

@krlmlr
Copy link
Member

krlmlr commented Oct 19, 2020

Can you connect to the MariaDB server from your host with the mysql command? What arguments do you use?

@matteodelucchi
Copy link
Author

It's a MySQL server to which I connect with the arguments mentioned above (see "situation"). I read that the support of the R package RMySQL is not guaranteed anymore (didn't verify that though!) which is why I use RMariaDB to connect. I would like to mention that the connection can be established using the config file, it's just not very handy and would be much more convenient to specify the protocol as argument and updating the manual respectively.

@krlmlr
Copy link
Member

krlmlr commented Oct 20, 2020

I'm looking for ways to avoid adding an extra argument.

Can you connect with mysql --host=127.0.0.1 --port=6603 --user=root --password=secret ?

@matteodelucchi
Copy link
Author

No, this results in:

$ mysql --host=localhost --port=6603 --user=root --password=secret
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

Whereas in contrast specifying the protocol argument everything runs smoothly:

$ mysql --host=localhost --port=6603 --user=root --password=secret --protocol=tcp
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 25
Server version: 8.0.21 MySQL Community Server - GPL
[...]

@krlmlr
Copy link
Member

krlmlr commented Oct 20, 2020

What about mysql --host=127.0.0.1 --port=6603 --user=root --password=secret ?

@matteodelucchi
Copy link
Author

This works:

$ mysql --host=127.0.0.1 --port=6603 --user=root --password=secret
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 26
Server version: 8.0.21 MySQL Community Server - GPL
[...]

But analogously specifying the host in R doesn't:

> con <- dbConnect(RMariaDB::MariaDB(),
+                  dbname="dbname",
+                  username="root",
+                  password="secret",
+                  host = "127.0.0.1")
Error: Failed to connect: Can't connect to MySQL server on '127.0.0.1' (111)
> con <- dbConnect(RMariaDB::MariaDB(),
+                  dbname="dbname",
+                  username="root",
+                  password="secret",
+                  host = "localhost")
Error: Failed to connect: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

@krlmlr
Copy link
Member

krlmlr commented Oct 20, 2020

Does your first R code need port = ... ?

@matteodelucchi
Copy link
Author

My fault! Sry...

> con <- dbConnect(RMariaDB::MariaDB(),
+                  dbname="dbname",
+                  username="root",
+                  password="secret",
+                  host = "127.0.0.1",
+                  port = 6603)

Specifying host and port establishes successfully the connection. I wonder why the default host argument, which is NULL and corresponds to localhost, doesn't work...

> con <- dbConnect(RMariaDB::MariaDB(),
+                  dbname="dbname",
+                  username="root",
+                  password="secret",
+                  port = 6603)
Error: Failed to connect: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

@krlmlr
Copy link
Member

krlmlr commented Oct 20, 2020

The behavior is documented in ?dbConnect in this package.

I agree that your second example should switch to TCP/IP because you have specified a port. On the other hand, perhaps we really should follow the mysql semantics as you suggest and add a port argument?

Would you like to contribute a pull request?

@matteodelucchi
Copy link
Author

I'll do but it will take some time.

@krlmlr krlmlr added this to the 1.1.0 milestone Dec 26, 2020
@krlmlr krlmlr modified the milestones: 1.1.0, 1.2.0 Jan 5, 2021
@krlmlr
Copy link
Member

krlmlr commented Dec 12, 2021

We need to call mysql_options() with MYSQL_OPT_PROTOCOL in DbConnection::connect() .

@krlmlr krlmlr removed this from the 1.2.0 milestone Dec 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants