20211022のMySQLに関する記事は3件です。

DockerでPHPとMySQLのシンプルすぎる環境構築を行う

執筆に至った経緯 Docker使えたらカッコよくね? ↓ ネットに転がってる環境構築は強すぎて理解できなくね? ↓ 最小構成の環境構築を知って、そこから自分が必要な部分を拡張していったら理解できるんじゃね? 想定読者 Dockerの基礎的なことは何となく分かったが、実際に使ってみたい方。 他人の作ったDocker環境は使ったことがあるが、自分では構築したことがない方。 今回のゴール DockerでPHPとMySQLの環境構築を行う。 具体的には以下3つが実行できたら完了とする。 PHPコンテナ内に入り、helloworldを出力する。 MySQLコンテナ内に入り、適当なSQL文を実行する。 PHPからMySQLに接続する。 実行環境と筆者のレベル感 実行環境 OS : Windows10 Pro プロセッサ : 11th Gen Intel(R) Core(TM) i7-11370H @ 3.30GHz 3.00 GHz 実装RAM : 16.0GB システムの種類 : 64 ビット オペレーティング システム、x64 ベース プロセッサ DockerDesktop : 4.11 筆者のレベル感 2021年10月から勤務開始した新米エンジニア。 ともに育ちましょう。 ファイル構成 . |-- docker | |-- mysql | | |-- Dockerfile | | |-- data | `-- php | `-- Dockerfile |-- docker-compose.yml |-- src `-- index.php ステップ1 PHPのDockerfileを作成 Dockerfile FROM php:7.2-apache RUN apt-get update \ && docker-php-ext-install pdo_mysql mysqli mbstring WORKDIR /var/www/html EXPOSE 80 1行目 FROM命令でPHPのDockerイメージを引っ張ってくる。 「:」はタグと呼ばれるものでバージョンやオマケを指定することができる。 今回の場合は「PHPのバージョン7.2が欲しい、ついでにapacheつけといて」という意味。 DockerHubに色々載っていて楽しいので一読をおススメ。 2~3行目 RUN命令で各種パッケージのインストール等を行う。 apt-get updateでインストール可能なパッケージ一覧を更新する。 実際にインストール等は行わない。 バックスラッシュで改行できる。&&でコマンドとコマンドを繋ぐ。 docker-php-ext-installで各種拡張機能をインストール。 docker-php-ext-installはPHP標準拡張機能のインストーラー。 pdo_mysqlはPHPからMySQLに接続するための拡張機能。 mysqliもPHPからMySQLに接続するための拡張機能。 PDOかmysqliの二択っぽくて、片方だけでOKそうだが、両方学習したいのでどちらも入れておく。 mbstringはmb_substrみたいなマルチバイト文字列に対応したメソッドを使うための拡張機能。 5行目 WORKDIR命令でこの命令以降に実行したコマンドの作業場所およびコンテナに入った際のディレクトリを指定する。 だいたいどの記事を見てもこのパスが書いてあるので、とりあえずあまり難しく考えない方が良いのかも。 7行目 EXPOSE命令でコンテナのポート(玄関)を指定。 玄関を開けているだけなので、ホストとはまだ繋がってません。玄関の鍵だけ開けたっていう感じ。 実際にポートを開けているわけではない様子。コメント的役割のようですね。 参考文献の『DockerfileのEXPOSEは実際に何かポートを開けているわけではない』参照。 Dockerhubを見るに、php-apacheのイメージ内でWORKDIRやEXPOSEの設定はされているっぽい。 ステップ2 MySQLのDockerfileを作成 Dockerfile FROM mysql:8.0 EXPOSE 3306 1~3行目 FROM命令でMySQLイメージを引っ張ってきて、EXPOSE命令で3306番がコンテナのポートだと記載。 前述のとおりコメント的意味合いの様子。 M1 Macを使用の場合はbuild時にエラーが出るかも知れません。 執筆時点ではMySQLコンテナはM1対応してないみたいです。 回避方法ありまして、参考文献の『M1 MacでDockerを使った開発環境構築にハマった』参照。 ステップ3 docker-compose.ymlの作成 docker-compose.yml version: '3' services: app: build: context: ./docker/php dockerfile: Dockerfile volumes: - ./src:/var/www/html ports: - "80:80" depends_on: - db db: build: context: ./docker/mysql dockerfile: Dockerfile volumes: - ./docker/mysql/data:/var/lib/mysql ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=pass 1行目 docker-composeのバージョンを設定。 バージョンによって微妙に書き方が異なるっぽい。 2行目 servicesに使用するコンテナを列挙する。 今回はappコンテナとdbコンテナを作成。 4~6行目 build内にdocker-compose buildをした際の挙動を記述。 contextとはbuildコマンドを実行する場所。 今回はDockerfileのある場所を指定すれば良さそう。 dockerfileはDockerfileの場所を指定。 上記で./docker/phpでbuildコマンドを実行するところまでは指定しているので、ファイル名だけ記述。 7~8行目 volumesでローカルファイルをDockerコンテナ内に結び付ける。 ローカルのsrc以下のファイルがDockerコンテナ内の/var/www/html内にマウント(≒コピー)される。 ローカルのsrcにファイルを置くと、Dockerコンテナ内の指定しているディレクトリにコピーされ、逆もまた然り。 9~10行目 コンテナのポート(玄関)とホストのポート(玄関)の間に道を作る。 これでホスト側でlocalhost:80にアクセスすると、コンテナの80にアクセスされる。 コンテナ側の80番は決まっている値なので、Dockerhubでポートが何番かを確認する。 11~12行目 このように設定すると、先にdbコンテナが立ち上がってから、appコンテナが立ち上がるようになる。 14~17行目 同様なので省略。 18~19行目 MySQLのデータをローカルにコピーしている。 そうしないとコンテナを消してしまうとデータが吹き飛ぶため。 20~21行目 同様なので省略。 22~23行目 MySQLの環境変数をここで定義。最低限ということでrootユーザーのパスワードのみ。 別にenvファイルを作成してマウントしてしまっても良いのかも。 動作検証 PHPコンテナ内に入り、helloworldを出力する。 何はともあれコンテナ起動 $ docker compose up -d index.phpにhelloworldを実装 index.php echo 'helloworld'; PHPコンテナ内に入って、実行して無事出力を確認 ちなみにコンテナからはexitで出られます。 $ docker compose exec app bash root@123456789123:/var/www/html# php index.php helloworld MySQLコンテナ内に入り、適当なSQLを実行する。 $ docker compose exec db bash root@987654321987:/# mysql -u root -p Enter password: #docker-compose.ymlで定義したパスワードを入力 mysql > SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.00 sec) PHPからMySQLに接続する。 今回はmysqliを使ってデータベースへ接続。 new mysqliの第1引数にはデータベースのコンテナ名を記載。 第2引数と第3引数にログインするユーザーの名前とパスワードを渡す。 rootユーザーは初期状態で設定されていて、パスワードはdocker-compose.ymlで設定済。 index.php $mysqli = new mysqli('db', 'root', 'pass', 'mysql'); if($mysqli->connect_error) { echo '接続失敗'.PHP_EOL; exit(); } else { echo '接続成功'.PHP_EOL; } PHPコンテナ内に入って接続成功を確認。 MySQLコンテナ内で一部設定変更しないとエラーが出ます。 参考文献の『MySQL8.0 認証方式を変更する(Laravel5)』参照のこと。 $ docker compose exec app bash root@123456789123:/var/www/html# php index.php 接続成功 今後の課題 php.iniとmy.cnfを設定する。 PHPのデバッグが出来る環境を構築する。 実際にPHPからMySQLへデータの挿入および呼び出しを行う。 その他必要な拡張機能を追加していく。 参考文献 以下のサイトおよび記事を参考にさせていただきました。 ありがとうございます! ・Docker初心者のDockerfileを理解する ・docker-compose.ymlのbuild設定はとりあえずcontextもdockerfileも埋めとけって話 ・Docker Composeでphpでmysqlにアクセスする ・docker-composeでPHPとMySQLを連携させてみる ・【PHP】peclとは何か?pecl install と docker-php-ext-installの違い ・mysqli の忘備録 -PDOとmysqliの違い- ・[PHP] mysqli使い方まとめ(MySQL接続~SELECT実行まで) ・MySQL8.0 認証方式を変更する(Laravel5) ・【MySQL】PHPで接続できないとき ・M1 MacでDockerを使った開発環境構築にハマった ・DockerfileのEXPOSEは実際に何かポートを開けているわけではない
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MySQLがbundle installできない

備忘録。 初学者ですが、rbenvやMySQL周りでエラーになること多い。 エラー文 An error occurred while installing mysql2 (0.5.3), and Bundler cannot contniue. とあり、その ファイルのログをみると、 Don't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load Setting libpath to /usr/local/Cellar/mysql/8.0.26/lib creating Makefile と書いてある。 ログ通りlibPATHを設定してみた。 bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib" と打ったら解決。無事bundleinstallでmysql入りました。 参考https://qiita.com/tktcorporation/items/0ef8c930fc18ce72c301
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MySQLが過負荷で重い時にボトルネックになっているクエリ(プロセス)を一斉にKillして楽になる方法

DBサーバが過負荷に陥った時、ボトルネックとなっているクエリを一気に消したいことがあります。 show processlist で確認はできるのですが、そこから一気に消す方法について記録しておきます。 全てを消してしまうとまずいこともあるのでwhereで絞りながら一気に消します。 利用には mysqladmin と xargs を使っています。 下記のようにして行います。 information_schema.processlist から where を使って select (バージョンによってはperformance_schemaかもしれません) xargs と mysqladmin kill で全てkill もちろんですが、ボトルネックの原因となっているクエリ自体を見直さないと問題の解決になりません。 準備 サーバ接続用の環境変数を設定しておきます。 export DB_HOST=mysql.example.com export DB_USER=username export DB_PASS=password 一覧の確認 まずはどういったプロセスが動いているか確認します。 $ mysql -h${DB_HOST} -u${DB_USER} -p${DB_PASS} -e "SELECT * FROM information_schema.processlist where command != 'Sleep'\G" ... *************************** 1. row *************************** ID: 123 USER: username HOST: 10.10.10.10:1010 DB: dbname COMMAND: Execute TIME: 4 STATE: Sending data INFO: SELECT * from users; ... 該当クエリの調整 killしたい対象のプロセスを絞り込むようなWHERE句を書きます。下記ではusersが含まれる実行中のプロセスを抜き出しています。 $ export DB_WHERE="info like '%users%'" $ mysql -h${DB_HOST} -u${DB_USER} -p${DB_PASS} -e "SELECT * FROM information_schema.processlist where command != 'Sleep' and ${DB_WHERE};" IDだけをうまく抜き出すようにします。パイプで渡すと出力される枠などはきれいに無くなりxargsに渡せるようになります。 -Nでヘッダーが消えます。 $ mysql -h${DB_HOST} -u${DB_USER} -p${DB_PASS} -N -e "SELECT ID FROM information_schema.processlist where command != 'Sleep' and ${DB_WHERE};" | cat kill xargsを使ってkillします。 $ mysql -h${DB_HOST} -u${DB_USER} -p${DB_PASS} -N -e "SELECT ID FROM information_schema.processlist where command != 'Sleep' and ${DB_WHERE};" | xargs -n 1 mysqladmin kill -h${DB_HOST} -u${DB_USER} -p${DB_PASS} 良いインフラライフをお送りください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む