[7] [DFN[MySQL]] は、[[データベース]]です。

* MySQL over TLS

[2] [[TLS]] が有効かどうかは [CODE[SHOW STATUS LIKE "Ssl_cipher"]] で確認できます。
適当な [[cipher]] が返ってきたら、 [[TLS]] が有効です。

[3] [KBD[mysql]] [[コマンド]]ほかいくつかの[[クライアントライブラリー]]は
[[TLS]] が指定されていてもそれが適用されなかった場合にも、これをエラーとしないので、
注意が必要です。

[33] mysql クライアントから ClearDB サーバーに接続するには

[PRE(code bash)[
$ mysql --user=XXX --password=XXX --host=XXX XXX --ssl-ca=cleardb-ca.pem --ssl-cert=XXX-cert.pem --ssl-key=XXX-key.pem
]PRE]

最初の4つのXXXは Heroku の設定変数として設定されている CLEARDB_DATABASE_URL の値から採る。最後の3つのファイルは Heroku の設定ページから ClearDB のページに行き、ダウンロードする (ログイン必要なのでブラウザで保存する)。

秘密鍵のエラーが出る時は (OpenSSL のバージョンの問題らしい)、
[PRE(code bash)[
$ openssl rsa -in XXX-key.pem -out XXX-key-pkcs1.pem
]PRE]
... として作られたファイルを指定すれば良い。

本当に SSL で接続できたかは
[PRE(code bash)[
SHOW STATUS LIKE 'Ssl_cipher';
]PRE]
... で値が空文字列になっていないかどうかで確認できる。
[TIME[2014-10-12]]

[34] Perl の DBI で接続する時は
[PRE(code)[
DBI:mysql:database=%s;host=%s;user=%s;password=%s;mysql_ssl=1;mysql_ssl_ca_file=%s;mysql_ssl_client_cert=%s;mysql_ssl_client_key=%s
]PRE]
... のような dsn で同じ要領で接続できる。ただし DBD::mysql は標準では SSL 無効でコンパイルされる。その場合 mysql_ssl* は無視されるので注意しないといけない。無視されるがエラーにならずに平文で接続できてしまう。

DBD::mysql インストール時の Makefile.PL でオプション --ssl をつけると SSL 付きでコンパイルされる。 cpanm でインストールするなら --configure-args=--ssl をつければ良い。 pmbp.pl を使うなら今日の版以降は標準で --ssl 付きでコンパイルされる。

SSL なしで接続できてしまうのは怖いが、 MySQL で SSL 固定にするには GRANT ほにゃららを実行するらしい。 ClearDB では GRANT を実行する権限がなさそう (未確認)。

接続時に SHOW STATUS LIKE 'Ssl_cipher' して確認する実装にしておかないと怖い。
[TIME[2014-10-12]]

[35] AnyEvent::MySQL は SSL に対応していない。
[TIME[2014-10-12]]

* Docker 版

[30] [CITE[mysql/mysql-server - Docker Hub]] ([TIME[2017-03-19 19:09:03 +09:00]] 版) <https://hub.docker.com/r/mysql/mysql-server/>

[4] [CITE@ja[Dockerの公式MySQLイメージの使い方を徹底的に解説するよ · DQNEO起業日記]]
( ([TIME[2016-06-14 17:32:26 +09:00]]))
<http://dqn.sakusakutto.jp/2015/10/docker_mysqld_tutorial.html>

[6] ([TIME[2016-08-15 18:36:29 +09:00]])
<https://hub.docker.com/_/mysql/>

[31] なぜかサーバーが起動せず、 [CODE[docker logs]] を見ても特にエラーも無いときは、
[CODE[docker]] の [CODE[-d]] を付けずに実行すると、エラーが出ていることがあります。

[32] [[環境変数]]の組み合わせが間違っているとかで、わりと簡単に >>31 のような状況になるようです。

[36] [[CircleCI]] で実行すると [CODE[mbind: Invalid argument]]
というエラーが出まくるようですが、これ自体は無視して構わず、そのまま起動するなら問題ないようです。
[TIME[2018-05-18T13:51:43.00Z]]

* [CODE(URI)@en[mysql:]] URL scheme

[8] [CITE[Extended indexing features]] <http://www.dataparksearch.org/dpsearch-extended-indexing.en.html#htdb>
([TIME[2006-03-20 13:56:51 +00:00]])

[FIG(quote)[ [9] [SRC[>>8]]
>
[PRE(code URI)[
mysql://foo:bar@localhost/search/?dbmode=single
]PRE]
]FIG]

[10] [CITE@en[Engine Configuration — SQLAlchemy 0.7 Documentation]]
( ([TIME[2012-10-28 05:05:12 +09:00]] 版))
<http://docs.sqlalchemy.org/en/rel_0_7/core/engines.html#database-urls>

[11] [CITE[felixge/node-mysql · GitHub]] ([TIME[2013-05-09 08:29:39 +09:00]] 版) <https://github.com/felixge/node-mysql>

[12] [[mysqld]] の既定の[[ポート番号]]は [N[3306]]。

[FIG(quote)[
[FIGCAPTION[
[13] [CITE[Mojo::MySQL5::URL - search.cpan.org]]
([TIME[2015-07-09 00:25:59 +09:00]] 版)
<http://search.cpan.org/dist/Mojo-MySQL5/lib/Mojo/MySQL5/URL.pm>
]FIGCAPTION]


>
[PRE(perl code)[
  my $url = Mojo::MySQL5::URL->new('mysql://sri:foo@server:3306/test?foo=bar');
]PRE]

]FIG]

[5] 他にも色々バリエーションがあるようです。
[FIG(list middle)[
- [DFN[[CODE(URI)@en[mysql2:]]]]
- [DFN[[CODE(URI)@en[mysql+zxjdbc:]]]]
- [DFN[[CODE(URI)@en[mysql+mysqlconnector:]]]]
- [DFN[[CODE(URI)@en[mysql+cymysql:]]]]
- [DFN[[CODE(URI)@en[mysql+pymysql:]]]]
- [DFN[[CODE(URI)@en[mysql+gaerdbms:]]]]
- [DFN[[CODE(URI)@en[mysql+pyodbc:]]]]
- [DFN[[CODE(URI)@en[mysql+mysqldb:]]]]
- [DFN[[CODE(URI)@en[mysqlgis:]]]]
- [DFN[[CODE(URI)@en[mysqli:]]]]
]FIG]

* MySQL プロトコル

[REFS[
- [1] [CITE@en[MySQL :: MySQL Internals Manual :: 14 MySQL Client/Server Protocol]] ([TIME[2014-10-12 05:41:20 +09:00]] 版) <http://dev.mysql.com/doc/internals/en/client-server-protocol.html>
]REFS]

** [CODE[caching_sha2_password]]


[45] 
[CITE@en[MySQL :: MySQL 8.0.4 : New Default Authentication Plugin : caching_sha2_password]], [TIME[2024-01-19T07:20:48.000Z]] <https://dev.mysql.com/blog-archive/mysql-8-0-4-new-default-authentication-plugin-caching_sha2_password/>

[50] 
[CITE@en[MySQL :: Preparing your Community Connector for MySQL 8 – part 2 – SHA256]], [TIME[2024-01-23T10:40:20.000Z]] <https://dev.mysql.com/blog-archive/preparing-your-community-connector-for-mysql-8-part-2-sha256/>


[46] [CITE[MySQL: Caching_sha2_password information]], [TIME[2024-01-19T07:20:59.000Z]] <https://dev.mysql.com/doc/dev/mysql-server/latest/page_caching_sha2_authentication_exchanges.html>

[47] 
[CITE@ja[caching_sha2_passwordの仕様の話 - amamanamam]], [TIME[2024-01-19T07:21:08.000Z]] <https://amamanamam.hatenablog.com/entry/2023/11/20/215121>

[48] 
[CITE[MySQL: Protocol::HandshakeResponse:]], [TIME[2024-01-19T07:29:14.000Z]] <https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_packets_protocol_handshake_response.html>


[49] 
ひたすら面倒になっただけに見えるんだが... これ意味あるのかなあ?

* SQL

[41] 
[[GIS]] 系の [[SQL]] [[関数]]の古いもの ([[非推奨]]になっていたもの)
は 
[[MySQL]] 8 で廃止されて削除されて使えなくなってしまったようです。

[42] 
だいたいは先頭に [CODE[ST_]] をつければいいのですが、
[CODE[GLength]] は [CODE[ST_Length]] になるなど注意が必要なものもあります。

[43] 
こういう[[非互換変更]]、やめてほしいですね。

* メモ


[FIG(quote)[
[FIGCAPTION[
[14] [CITE@en[MySQL :: MySQL Connector/J 5.1 Developer Guide :: 5.1 Driver/Datasource Class Names, URL Syntax and Configuration Properties for Connector/J]]
([TIME[2016-11-17 21:53:23 +09:00]])
<https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-configuration-properties.html>
]FIGCAPTION]

> The general format for a JDBC URL for connecting to a MySQL server is as follows, with items in square brackets ('''[''' ''']''') being optional:
> jdbc:mysql://'''['''host1''']''''''[''':port1''']''''''[''','''['''host2''']''''''[''':port2''']'''''']'''...'''['''/'''['''database''']'''''']''' »
> '''['''?propertyName1=propertyValue1'''['''&propertyName2=propertyValue2''']'''...''']'''
> Here is a simple example for a connection URL:
> jdbc:mysql://localhost:3306/sakila?profileSQL=true

]FIG]


[FIG(quote)[
[FIGCAPTION[
[15] [CITE@en[MySQL :: MySQL Connector/J 5.1 Developer Guide :: 5.1 Driver/Datasource Class Names, URL Syntax and Configuration Properties for Connector/J]]
([TIME[2016-11-17 21:54:08 +09:00]])
<https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-configuration-properties.html>
]FIGCAPTION]

> The following is an alternate format for JDBC URLs connecting to a MySQL server, which is mandatory for IPv6 connections, but can also be used with IPv4 (items in square brackets ('''[''' ''']''') are optional):
> jdbc:mysql://address=(key1=value)'''['''(key2=value)''']'''...'''[''',address=(key3=value)'''['''(key4=value)''']'''...''']'''...'''['''/'''['''database''']'''''']'''»
> '''['''?propertyName1=propertyValue1'''['''&propertyName2=propertyValue2''']'''...''']'''
> Supported key-value pairs include:
> (protocol=tcp), or (protocol=pipe) for named pipes on Windows.
> (path=path_to_pipe) for path of named pipes. Default value for the path is \\.\pipe\MySQL. Use the key-value pair to specify a custom named pipe.
> (host=hostname) for TCP connections.
> (port=port_number) for TCP connections.
> For example:
> jdbc:mysql://address=(protocol=tcp)(host=localhost)(port=3306)/db

]FIG]


[FIG(quote)[
[FIGCAPTION[
[16] [CITE@en[mysqljs/mysql: A pure node.js JavaScript Client implementing the MySql protocol.]]
([TIME[2016-11-17 21:56:26 +09:00]])
<https://github.com/mysqljs/mysql>
]FIGCAPTION]

> In addition to passing these options as an object, you can also use a url string. For example:
> var connection = mysql.createConnection('mysql://user:pass@host/db?debug=true&charset=BIG5_CHINESE_CI&timezone=-0700');
> Note: The query values are first attempted to be parsed as JSON, and if that fails assumed to be plaintext strings.

]FIG]


[FIG(quote)[
[FIGCAPTION[
[17] [CITE@en[mysql/ConnectionConfig.js at master · mysqljs/mysql]]
([TIME[2016-11-17 22:00:25 +09:00]])
<https://github.com/mysqljs/mysql/blob/master/lib/ConnectionConfig.js>
]FIGCAPTION]

> 
>   if (url.query) {
>     for (var key in url.query) {
>       var value = url.query'''['''key''']''';
>       try {
>         // Try to parse this as a JSON expression first
>         options'''['''key''']''' = JSON.parse(value);
>       } catch (err) {
>         // Otherwise assume it is a plain string
>         options'''['''key''']''' = value;
>       }
>     }
>   }

]FIG]


[FIG(quote)[
[FIGCAPTION[
[18] [CITE@en[Engine Configuration — SQLAlchemy 0.9 Documentation]]
([TIME[2016-11-05 07:07:26 +09:00]])
<http://docs.sqlalchemy.org/en/rel_0_9/core/engines.html#database-urls>
]FIGCAPTION]

> # default
> engine = create_engine('mysql://scott:tiger@localhost/foo')
> # mysql-python
> engine = create_engine('mysql+mysqldb://scott:tiger@localhost/foo')
> # MySQL-connector-python
> engine = create_engine('mysql+mysqlconnector://scott:tiger@localhost/foo')
> # OurSQL
> engine = create_engine('mysql+oursql://scott:tiger@localhost/foo')

]FIG]


[FIG(quote)[
[FIGCAPTION[
[19] [CITE@en[MySQL — SQLAlchemy 0.9 Documentation]]
([TIME[2016-11-05 07:07:26 +09:00]])
<http://docs.sqlalchemy.org/en/rel_0_9/dialects/mysql.html>
]FIGCAPTION]

> mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>

> mysql+mysqldb://root@/<dbname>?unix_socket=/cloudsql/<projectid>:<instancename>

> mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]

> mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>

> mysql+cymysql://<username>:<password>@<host>/<dbname>[?<options>]

> mysql+oursql://<user>:<password>@<host>[:<port>]/<dbname>

> mysql+mysqldb://root@/<dbname>?unix_socket=/cloudsql/<projectid>:<instancename>

> mysql+gaerdbms:///<dbname>?instance=<instancename>

> mysql+pyodbc://<username>:<password>@<dsnname>

> mysql+zxjdbc://<user>:<password>@<hostname>[:<port>]/<database>

]FIG]


[FIG(quote)[
[FIGCAPTION[
[20] [CITE@en[ClearDB MySQL | Heroku Dev Center]]
([TIME[2016-11-17 22:19:12 +09:00]])
<https://devcenter.heroku.com/articles/cleardb>
]FIGCAPTION]

> You can retrieve your new ClearDB database URL by issuing the following command:
> $ heroku config | grep CLEARDB_DATABASE_URL
> CLEARDB_DATABASE_URL => mysql://adffdadf2341:adf4234@us-cdbr-east.cleardb.com/heroku_db?reconnect=true
> To set your DATABASE_URL to the value of CLEARDB_DATABASE_URL, simply issue the following heroku command. For example:
> If you’re using the mysql2 gem, you will need to change the mysql:// scheme in the CLEARDB_DATABASE_URL to mysql2://

]FIG]


[FIG(quote)[
[FIGCAPTION[
[21] [CITE@en[ClearDB MySQL | Heroku Dev Center]]
([TIME[2016-11-17 22:20:25 +09:00]])
<https://devcenter.heroku.com/articles/cleardb>
]FIGCAPTION]

> To instantiate a JDBC connection in your code, you can use a method like this:
> private static Connection getConnection() throws URISyntaxException, SQLException {
>     URI dbUri = new URI(System.getenv("CLEARDB_DATABASE_URL"));
>     String username = dbUri.getUserInfo().split(":")'''['''0''']''';
>     String password = dbUri.getUserInfo().split(":")'''['''1''']''';
>     String dbUrl = "jdbc:mysql://" + dbUri.getHost() + dbUri.getPath();
>     return DriverManager.getConnection(dbUrl, username, password);
> }

]FIG]

[FIG(quote)[
[FIGCAPTION[
[22] [CITE@en[kennethreitz/dj-database-url]]
([TIME[2015-07-09 00:47:23 +09:00]] 版)
<https://github.com/kennethreitz/dj-database-url>
]FIGCAPTION]

> MySQL (GIS)	django.contrib.gis.db.backends.mysql	mysqlgis://USER:PASSWORD@HOST:PORT/NAME

]FIG]


[FIG(quote)[
[FIGCAPTION[
[23] [CITE@en[julianwachholz/dj-config-url: Use 12factor inspired URLs to configure your Django Application.]]
([TIME[2016-11-17 22:45:48 +09:00]])
<https://github.com/julianwachholz/dj-config-url>
]FIGCAPTION]

> 
> MySQL	django.db.backends.mysql	mysql://USER:PASSWORD@HOST:PORT/NAME
> MySQL (GIS)	django.contrib.gis.db.backends.mysql	mysqlgis://USER:PASSWORD@HOST:PORT/NAME

]FIG]


[FIG(quote)[
[FIGCAPTION[
[24] [CITE@en[prometheus/promdash: Prometheus Dashboard Builder]]
([TIME[2016-11-17 23:18:14 +09:00]])
<https://github.com/prometheus/promdash>
]FIGCAPTION]

> DATABASE_URL="mysql2://username:password@host/database"

]FIG]


[FIG(quote)[
[FIGCAPTION[
[25] [CITE[java - JDBC MySQL connection using Unix Socket - Stack Overflow]]
([TIME[2016-11-17 23:47:01 +09:00]])
<http://stackoverflow.com/questions/25918416/jdbc-mysql-connection-using-unix-socket>
]FIGCAPTION]

> If you want to use UNIX sockets with the Mysql JDBC Connector/J you need to provide a socketFactory.
> jdbc:mysql:///?user=test&password=test&socketFactory=<classname>&<socket>=/tmp/mysql.sock
> So this will vary with the implementation you use. By default, Mysql does not ship with any implementation for that, just provides an example for such a factory in it's source-code.

]FIG]


[FIG(quote)[
[FIGCAPTION[
[26] [CITE[java - JDBC MySQL connection using Unix Socket - Stack Overflow]]
([TIME[2016-11-17 23:47:30 +09:00]])
<http://stackoverflow.com/questions/25918416/jdbc-mysql-connection-using-unix-socket>
]FIGCAPTION]

> As another answer pointed out, it's possible (at least in Intellij IDE) to use socket connection for Mysql JDBC Connector/J (I am using version 5.1) without having to provide a socketFactory,
> jdbc:mysql://localhost:3306/database_name?socket=/tmp/mysql.sock

]FIG]


[FIG(quote)[
[FIGCAPTION[
[27] [CITE[java - JDBC MySQL connection using Unix Socket - Stack Overflow]]
([TIME[2016-11-17 23:48:01 +09:00]])
<http://stackoverflow.com/questions/25918416/jdbc-mysql-connection-using-unix-socket>
]FIGCAPTION]

> The JDBC Driver from the MariaDB project supports Unix domain sockets while remaining compatible with the MySQL Connector/J JDBC driver. Example jdbc url for the MariaDB driver is: jdbc:mariadb://localhost:3306/revmgt?localSocket=/var/run/mysqld/mysqld.sock

]FIG]


[FIG(quote)[
[FIGCAPTION[
[28] [CITE[Manual :: The Data Source Name]]
([TIME[2016-11-17 23:52:57 +09:00]])
<http://pear.php.net/manual/en/package.database.db.intro-dsn.php>
]FIGCAPTION]

> 
> mysql  -> MySQL (for MySQL <= 4.0)
> mysqli -> MySQL (for MySQL >= 4.1) (requires PHP 5) (since DB 1.6.3)

]FIG]


[FIG(quote)[
[FIGCAPTION[
[29] [CITE[The DB-URI — TurboGears 1.0 documentation]]
([TIME[2013-01-12 16:52:59 +09:00]])
<http://turbogears.org/1.0/docs/DbUri.html>
]FIGCAPTION]

> To specify the socket file for MySQL, you need to use the unix_socket option:
> mysql://localhost/database?unix_socket=/var/lib/mysql/socket

]FIG]


[37] [CITE[Client/Server Protocol - MariaDB Knowledge Base]]
([TIME[2018-08-30 19:21:43 +09:00]])
<https://mariadb.com/kb/en/library/clientserver-protocol/>

[38] [CITE[library/mariadb - Docker Hub]]
([TIME[2018-08-30 19:31:01 +09:00]])
<https://hub.docker.com/_/mariadb/>

[39] [CITE[mysql - SQLSTATE'''['''HY000''']''': General error: 1835 Malformed communication packet on LARAVEL - Stack Overflow]]
([TIME[2020-11-05T07:47:55.000Z]])
<https://stackoverflow.com/questions/64677836/sqlstatehy000-general-error-1835-malformed-communication-packet-on-laravel>

[40] [CITE@en['''['''MDEV-24121''']''' Recent MariaDB update appears to have introduced a DB connection issue for PHP < 7.3 (or anything using PDO) - Jira]]
([TIME[2020-11-05T07:50:11.000Z]])
<https://jira.mariadb.org/browse/MDEV-24121>

[44] [SEE[ [[MariaDB]] ]]

>Can't initialize timers

