20210306のMySQLに関する記事は5件です。

MySQLのサンプルデータをXAMPPにインポートする

ちょっとしたクエリを実験するためにサンプルデータが欲しいなあ、と思っていたらMySQLに用意されているそうではないか!
employeeという仮想社員データ? をXAMPPくんのMySQLに取り込んで使ってみました。

サンプルデータのダウンロード

ここからダウンロード
https://dev.mysql.com/doc/index-other.html

いくつかサンプルがあるので、好きなものを選んでいただければと思います。

employeeというサンプルが1番大きそうだったので、私はこいつを使いました。

MySQL_offcial.PNG

MySQLにインポート

  1. DLしたサンプルデータが入ったファイルを解凍
  2. XAMPPコントロールパネルのshellを起動
  3. cd (サンプルデータのパス) で移動
     自分の場合は "cd C:\Users\Sanada\Downloads\test_db-master" をshellに入れました
  4. "mysql -u root -p < employees.sql" を入力
     -uの後ろにはユーザー名
     -pの後ろにはパスワード
     デフォルトならpassを求められてもそのままEnterで大丈夫なはず
  5. "mysql -u root -p employees -e "select * from employees LIMIT 10;" を入力
     レコードが表示されれば問題なく取り込めています。

    あとはお好きにイジり倒しましょう
    XAMPPのphpMyAdminnから色々するもヨシ
    そのままコマンドラインでやるのもヨシ という具合で

ハマったこと

インポートするときの書き方が分からなくて若干詰まった
mysql <employees.sql
mysql < -u root -p employees.sql

こんな風に書いて何度か怒られました…

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MySQL 環境構築

MySQLの導入

1. MySQLのインストール

ターミナルに入力

% brew install mysql@5.6

2. MySQLの自動起動設定

自動で起動するように設定する。

% mkdir ~/Library/LaunchAgents 
% ln -sfv /usr/local/opt/mysql\@5.6/*.plist ~/Library/LaunchAgents
% launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql\@5.6.plist

3. mysqlコマンドをどこからでも実行できるようにする

rbenvやreadlineの時と同様に、どこからでもMySQLを操作するためのコマンドmysqlを実行できるようにする。

% echo 'export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"' >> ~/.zshrc # mysqlのコマンドを実行できるようにする設定
% source ~/.zshrc #  設定を読み込むコマンド
% which mysql # mysqlのコマンドが打てるか確認する

# 以下のように表示されれば成功
/usr/local/opt/mysql@5.6/bin/mysql

4. MySQLの起動を確認

% mysql.server status # MySQLの状態を確認するコマンド

# 以下のように表示されれば成功
 SUCCESS! MySQL running
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

環境構築 4 MySQL

MySQLの導入

1. MySQLのインストール

ターミナルに入力

% brew install mysql@5.6

2. MySQLの自動起動設定

自動で起動するように設定する。

% mkdir ~/Library/LaunchAgents 
% ln -sfv /usr/local/opt/mysql\@5.6/*.plist ~/Library/LaunchAgents
% launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql\@5.6.plist

3. mysqlコマンドをどこからでも実行できるようにする

rbenvやreadlineの時と同様に、どこからでもMySQLを操作するためのコマンドmysqlを実行できるようにする。

% echo 'export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"' >> ~/.zshrc # mysqlのコマンドを実行できるようにする設定
% source ~/.zshrc #  設定を読み込むコマンド
% which mysql # mysqlのコマンドが打てるか確認する

# 以下のように表示されれば成功
/usr/local/opt/mysql@5.6/bin/mysql

4. MySQLの起動を確認

% mysql.server status # MySQLの状態を確認するコマンド

# 以下のように表示されれば成功
 SUCCESS! MySQL running
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker(Mac)でgRPC FUSE有効時にMySQL8コンテナが起動しない問題について調査報告と解決策

はじめに

Docker環境でRailsアプリケーションを開発する際にDocker Desktop for MacのgRPC FUSEを有効にした状態でコンテナを起動すると、MySQL8のコンテナが起動しない問題が発生した。

こんな感じ

db_1     | 2021-03-05T17:42:39.341701Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
db_1     | 2021-03-05T17:42:40.003650Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
db_1     | 2021-03-05T17:42:40.011792Z 1 [ERROR] [MY-011087] [Server] Different lower_case_table_names settings for server ('2') and data dictionary ('0').
db_1     | 2021-03-05T17:42:40.012090Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed.
db_1     | 2021-03-05T17:42:40.012378Z 0 [ERROR] [MY-010119] [Server] Aborting
db_1     | 2021-03-05T17:42:40.618413Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.23)  MySQL Community Server - GPL.

この問題はDocker 2.4.0から報告されている有名な問題らしく、gRPC FUSEをオフにすることで改善できる問題とのことだった。
参考:Mysql not starting in a docker container on MacOS after docker update

しかし、(本来ここについても調査すべきなのかもしれないがw)gRPC FUSEをオフにすることで、docker-composeを起動中にアプリケーションに編集を加えるとコンテナやアプリケーションがフリーズして再起動を必要とする…ということが起きてしまったため、
なんとかgRPC FUSEを有効にした状態でMySQL8コンテナを起動することはできないか、自分なりに調査をしてみました。




あくまでも「私はこのように調査したよ、このように対処したよ」という報告のような内容の記事ですので、ここに書いてある内容が正しいノウハウ、知識という認識で読まれるのはオススメしません。
この記事をきっかけに正しい知恵をいただいたり、もしくはこの問題についての議論が進むことを望みます。

実行環境

  • MacBook Pro 16inch 2019
  • macOS 11.2.2

  • Docker Desktop for Mac 3.1.0 ※gRPC FUSEを有効にする

docker-composeファイルの設定

docker-compose.yml
  db:
    image: mysql:8.0.23
    command: mysqld --default-authentication-plugin=mysql_native_password
    volumes:
      - ./mysql/mysql:/var/lib/mysql

いろいろわかったこと(原因は不明)

再ビルドしても起動しなかった

再度ビルドをしてみてクリーンな状態で起動してみてはどうか、と考えたが改善しなかった。
--no-cacheオプションも試しましたが関係ありませんでした。

別のログインユーザーは正常に起動した

私のMacBookにはプライベート用とそれ以外用とでユーザーアカウントをわけている。
今回、テストしてみたところ、同じRailsアプリケーション、同じdokker-composeファイルにもかかわらず、プライベート用のユーザーアカウントでは問題なくMySQL8コンテナを起動することができた。
インストールしているアプリケーションや開発環境の内容はほぼいっしょ(のはず)のため、もう一方のユーザーアカウントで起動しなかった理由はわからず…

インターン生のPCでも正常に起動した

私の勤務している会社で働いてくれているインターン生のMacBookでも正常に起動していた。
こちらのMacBookは最近使い始められたばかりで、特に設定やアプリのインストールがされているわけではないので、それが原因で起動した説…はあるかもしれない。。。

Dockerのバージョンを上げてみたが改善せず…

無駄でした…なお、バージョンを下げるのはなんだか気分が乗らなかったのでやめた。

docker-compose run db bashでコンテナに入ってみた => データベースが読み込まれていなかった

gRPC FUSEをオフの状態でMySQLコンテナに入り、MySQLを起動すると、
RailsのActiveRecordで作成したデータベーステーブルをshow databases;で見つけることができた。

しかし、gRPC FUSEを有効にしてから同様の処理をすると…そもそもMySQLにすらログインさせてもらえなかった。
つまり、データベースが読み込まれていない、ということだ。

なるほど…ということは、MySQLのデータを永続化させるために設定しているVolumesが怪しいのでは…?

MySQLコンテナのvolumesの記述を削除すると…起動した

MySQLデータを永続化させるためのvolumes設定を削除してみたところ、、、ついに、MySQLコンテナが正常に動作してくれた。
しかし、このままでは毎回コンテナ起動時にデータベースを作成しなければいけない。うーん、どうしたらいいものか。

そして見つけた、自分なりの改善策

MySQLのデータのマウント先を名前付きVolumesに設定 => 起動した!

Volumesが怪しいと思いいろいろ調べてみたところ、こちらの記事を見つけることができた。

Docker上のMySQLのデータをVolumeでホストのディレクトリにマウントすると権限周りで面倒なことになる
Dockerのvolumeでpermission deniedが発生した場合の解決法

Macでは発生しない問題(?)についての記事ではあったのですが、この記事を見て名前付きVolumesを設定したらどうなるだろう、と思った。

docker-composeファイルの設定のうち、volumesの設定を以下のように変更してみました。

docker-compose.yml
  db:
    image: mysql:8.0.23
    command: mysqld --default-authentication-plugin=mysql_native_password
    volumes:
      - mysql_data:/var/lib/mysql
volumes:
  mysql_data:  # 名前付きVolumesを定義

すると…




動いた!!!(´;ω;`)




データもしっかり永続化できているので、docker-compose downしてから再度コンテナを起動させても、問題なくデータベースを読み込むことができた。
改めて思うと、永続化データをプロジェクトディレクトリ内にマウントする必要性も特に感じないので、名前付きVolumesに設定で全然問題ないんですよね。次からこのやり方で統一していこうと思います。




。。。しかし、今回MySQLコンテナをgRPC FUSE有効時にも正常動作させるのにかなり苦労したが、名前付きVolumesを使わずとも正常に動作する環境があるのも事実…なので完全な問題解決、理解には至っていないのだ。。。

おわりに

とりあえずの対処法は発見できたものの、まだこの問題の根本的な解消には至っていないと考えています。Dockerに対しての理解が浅いために、この程度までの調査、分析しかできませんでした。
今年に入ってこの問題に関する記事が新規で上がっていないところを見ると、皆さんすでに解決済み?なのかもしれませんが、もしかしたら今も困っている方がいらっしゃるかもしれません。

もし、この問題の原因、解決法に詳しい方がいらっしゃいましたらコメント欄でご教授いただけますと幸いです。
この記事が、DockerのgRPC FUSE問題に苦しむ方の解決のきっかけにつながることを願います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

NimだけでMySQLにアクセスしたい

外部ライブラリに頼りたくない

NimでMySQLに接続する際は標準ライブラリのdb_mysqlを使用するのが一般的である(と思う)。しかし、db_mysql(正確には依存先のmysql)はMySQLクライアント用ライブラリを動的ロードするため、(ビルド環境ではなく)実行環境に下表のライブラリを用意する必要があるが、手間がかかるだけでなく外部ライブラリの変更に弱い。
そこで外部ライブラリに依存しない方法をとりたい。

OS 必要ライブラリ
Linux libmysqlclient.so
Windows libmysql.dll(参考)
MacOS libmysqlclient.dylib

備考:Nimでは外部ライブラリのインターフェースをnimファイル内で定義する必要があるのだが、現在のNimのmysqlライブラリとMySQLクライアントライブラリのインターフェースに差異がある。MySQLライブラリのインターフェースはバージョン毎に微妙に異なるのでNimのFFIの仕組みとは相性が悪いのではと感じる。

Golangはどうしてる?

Golangでは標準ライブラリとして各DB共通インターフェースdatabase/sqlを用意し、実装は各Driverライブラリに任されているが、MySQL用Driverの中で最もスタンダードである(と思う)go-sql-driver/mysqlでは全てGolangで実装されていて外部ライブラリを必要としない。

じゃあNimでも書けばいいじゃん

ということで、NimでMySQL接続用のライブラリを書いてみようと思ったが、まずはどんなプロトコルでMySQLとやり取りするのかを調べないといけない。

そこで以下のページでプロトコルの概要を調べるとTCPを使いMySQLのClient/Server Protocolに則って通信すれば良いと分かった。

NimでTCP通信するにはnetasyncnetを使えばいいらしいのだが今回は簡単のためにnetを使うことにした。

あとはMySQLの公式リファレンスを見たり、良く分からないところはgo-sql-driver/mysqlを参考にしたりしてコードを書いてみる。

とりあえずはMySQLに接続できた

認証方法がmysql_native_passwordにしか対応できてない(MySQL8.0ではデフォルトがcaching_sha2_passwordになった)とか色々あるけど、LinuxとWindowsでMySQLに接続してSQLを実行することに成功した。(Macは持ってない)

接続用ライブラリ

サンプル

サンプル用docker-compose
version: '3.8'

services:

  db:
    image: mysql:8.0.23
    command: >
      --default-authentication-plugin=mysql_native_password
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci
    restart: always
    ports:
      - "3306:3306"
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: 1
      MYSQL_DATABASE: test
      MYSQL_USER: nim
      MYSQL_PASSWORD: nim
サンプルプログラム
import pure_db_mysql

proc main()=
  var db = db_open("127.0.0.1:3306", "nim", "nim", "test")
  defer: db.db_close()

  let drop_sql = 
    sql"""DROP TABLE IF EXISTS `user`"""
  let create_sql = sql"""
    CREATE TABLE IF NOT EXISTS `user` (
    `id` int NOT NULL,
    `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '',
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"""

  db.exec(drop_sql)
  db.exec(create_sql)

  let insert_args = 
    @[
      @["1","Tom"],
      @["2","Jay"],
      @["3","Ann"]
    ]

  for insert_arg in insert_args:
    db.exec(sql"INSERT INTO user VALUES (?, ?)", insert_arg)
  let rows = db.get_all_rows(sql"SELECT * FROM user WHERE id >= ? ORDER BY id", 2)

  echo rows

main()
結果
@[@["2", "Jay"], @["3", "Ann"]]

道のりは遠い

正常系で動くものはできたが、実運用に使えるレベルにはないのでこれから勉強しながらエラーハンドリングやいろんな機能追加をできたらいいな。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む