- 投稿日:2020-03-18T21:22:30+09:00
Mysql2::Error
MySQLが起動しない。
エラー内容
Mysql2::Error::ConnectionError (Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)):前日まで問題なくRailsの勉強をしていました。作成したアプリケーションを確認するために
rails sするとエラーがでました。
仮説
MySQLへアクセスするためのsockファイルを見つけれずアクセスできない。
トラブル解決手順
1.ターミナルに下記のコードを入力しデータベースの中身を見る。
$ ls -la /usr/local/var/mysql/すると
total 380944 drwxr-xr-x 66 _mysql _mysql 2112 3 17 23:50 . drwxrwxr-x 4 user admin 128 12 12 00:27 .. drwx------ 11 _mysql _mysql 352 1 26 17:54 DataBaseDesignSample_development drwx------ 3 _mysql _mysql 93 1 26 17:15 DataBaseDesignSample_test drwx------ 9 _mysql _mysql 283 2 11 19:28 ajax_development drwx------ 3 _mysql _mysql 36 2 11 19:27 ajax_test -rw-rw---- 1 _mysql _mysql 56 12 12 00:30 auto.cnf -rw-r----- 1 _mysql _mysql 0 2 15 15:53 binlog.index上記のような感じで表示される。
2.次に下記のコードを入力
$ ls -la /usr/local/var/実行すると下記のような表示が出る。問題なさそう.....
drwxrwxr-x 4 user admin 128 12 12 00:27 . drwxr-xr-x 13 root wheel 430 1 31 21:15 .. drwxrwxr-x 4 user admin 128 12 12 00:03 homebrew drwxr-xr-x 36 _mysql _mysql 3112 3 17 23:50 mysql3.このコードを入力するとエラーが解決!
$ sudo mysql.server start Starting MySQL ... SUCCESS!ちなみに下記のコードではエラーの解決にはいたりませんでした。
$ mysql.server restart最後に
同じ初学者の方は似たようなエラーで悩まされてると思います。
restartではなくstartと入力すること、初めにsudoと入力することでもっと強力な指令となるみたいです。
同じエラーで困る人のお役に立てればと思い投稿しました。
初学者の皆さん一緒に頑張りましょう!
- 投稿日:2020-03-18T19:18:07+09:00
さよならMariaDB5.5こんにちはMySQL8.0
CentOS7以降MariaDBがデフォになっちまったよおい!
そのままである。
互換性が高いため別に問題はないのであろうと思われるが、使い慣れているMySQLにもどしちくり~と開発陣に言われたので作業することになった。
ついでに最新のMySQL8.0にしといて^^^^とも言われた。やれやれ。コマンドレッツゴー
※別の人が作った社内開発環境で作業したため普通じゃない箇所があります(特にサービス名)。コピペで動かなくてもごめんなさい。
各種バックアップは取っておいてね!dumpやらconfigやら
systemctl stop mysql
何はともあれstop。確認もね。
yum remove Maria*
MariaDB関係を削除まずはmysql5.7を導入だ!いきなりmysql8.0へはいけなかったぞ!
yum install http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
mysql5.7のRPMパッケージインストール
yum info mysql-community-server
mysql5.7がインストールできるか確認
yum install mysql-community-server
mysql5.7インストール
mysqld --version
バージョン確認
systemctl start mysqld
mysql5.7開始!確認もネモネ。
mysql_upgrade -u root -p
データベースをmysql用にアップグレードここで動作確認しておくとよいかもね!
rpm -e mysql57-community-release
mysql5.7のRPMパッケージを削除
rpm -ivh https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
mysql8.0のRPMパッケージインストール
yum info mysql-community-server
mysql8.0がインストールできるか確認
systemctl stop mysqld
mysql5.7停止!確認m
yum install mysql-community-server
mysql8.0インストール
mysqld --version
バージョン確認
systemctl start mysqld
mysql開始!かk以上!閉廷!
私の環境ではこれで問題なく動作してました。おまけ
/etc/my.cnf
[mysqld]
default_authentication_plugin= mysql_native_password
my.cnfにこれを追記しておくといいかもしれない。mysql8.0でパスワードの認証方式が変わったので古いものに戻す設定だそうです。
- 投稿日:2020-03-18T19:00:26+09:00
DBの日時文字列をDATETIMEに変換したくてコケた話
なにが起きましたか
- とあるDBのテーブルでは,日時データが全て別カラムの文字列で構成されていた.
SELECT year, month,..., second from Hoge
みたいなやり方を強いられていた- これはプログラムでも扱いにくいしなんとかしたい.
- →MySQLなどでサポートされている
DATETIME
型に変換する.変換元のHogeテーブルと変換先のPiyoテーブルは以下のような見た目である.
> SHOW CREATE TABLE Hoge; CREATE TABLE Hoge (id, columns, year VARCHAR(4), month VARCHAR(2)...) > SHOW CREATE TABLE Piyo CREATE TABLE Piyo (id, columns, date DATETIME(6))やったこと
- HogeからPiyoに変換する以下のようなSQLを書いた
convert.sqlinsert into Piyo( id, columns, STR_TO_DATE( CONCAT( year,'-',month,'-',day,' ',hour,':',minute,':',second,'.',usecond ), '%Y-%m-%d %H:%i:%s.%f' ) ) select id, columns, from Hoge;取得したそれぞれを,
CONCAT
で結合して,DATETIMEフォーマットに合わせる.それをSTR_TO_DATE
でDATETIME型に変換して,新しいPiyoテーブルにINSERTする.
さて,動くような気もするが,動かない.ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')) from ...なんと,SyntaxErrorだと言われた.全く分からん......
解決
全くSQLをわかっていなかった.
INSERTするときINSERT先カラム名を指定しない場合,INSERT先のカラム名と一致している必要がある当たり前だ.
もしINSERT先とINSERT元の名前を違うものにしたかったらINSERT INTO テーブル名 (インサート先カラム名) VALUES (インサート元カラム名)
でやる.
あるいは,SELECTしたときにASでINSERT先の名前として別名をつけてやる必要がある.結論
SELECT時に別名をつける手法を採用した.
convert.sqlINSERT INTO Piyo( id, columns, date ) SELECT id,columns,STR_TO_DATE( CONCAT( year,'-',month,'-',day,' ',hour,':',minute,':',second,'.',usecond ),'%Y-%m-%d %H:%i:%s.%f' ) as date from Hoge;これで1時間以上溶かしてしまった...SQLのエラーがもっっっと親切だったら良かった(ない)
- 投稿日:2020-03-18T18:49:33+09:00
【rails db:createエラー】dependent dylib '/usr/local/opt/mysql/lib/libssl.1.1.dylib' not found for '/Library/Ruby/Gems/2.6.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle'
エラーをいろいろ試して解決しました。(めちゃくちゃな解決法ですが初心者なのでご容赦ください)
エラー内容
$ rails db:createしたところ
LoadError: dlopen(/Library/Ruby/Gems/2.6.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle, 0x0009): dependent dylib '/usr/local/opt/mysql/lib/libssl.1.1.dylib' not found for '/Library/Ruby/Gems/2.6.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle' - /Library/Ruby/Gems/2.6.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundleのエラーが発生。
'/usr/local/opt/mysql/lib/libssl.1.1.dylib'のファイルが無い?と書いてありました。解決方法
他の方の参考にはあまりならないかもしれません。。。
homebrewでmysqlをインストールすれば、/usr/local/opt/mysql/lib/libssl.1.1.dylibファイルができると思い、
https://qiita.com/narikei/items/cd029911597cdc71c516
を参考に$ brew install mysql $ mysql.server start $ bundle init $ bundle install --path=vendor/bundleを実施しました。
その後、アプリ内で改めて
$ rails db:createしたら、
Could not find mysql2-0.5.3 in any of the sources Run `bundle install` to install missing gems.というエラーが出たので、
$ bundle installしたら、
An error occurred while installing mysql2 (0.5.3), and Bundler cannot continue. Make sure that `gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/'` succeeds before bundling.のエラーが出ました。
https://qiita.com/fukuda_fu/items/463a39406ce713396403
を参考に$ bundle config --local build.mysql2 "--with-cppflags=-I/usr/local/opt/openssl@1.1/include" $ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl@1.1/lib" $ bundle installしたところ、成功しました。改めて、
$ rails db:createしたところ、
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)のエラーが出たので、
https://qiita.com/carotene4035/items/e00076fe3990b9178cc0
を参考に$ touch /tmp/mysql.sock $ mysql.server restartをした後
$ rails db:createで無事にデータベースが作成できました。
- 投稿日:2020-03-18T14:21:49+09:00
ひとこと掲示板をデータベースで管理
ひとこと掲示板にて、利用者の過去発言内容をデータベースで管理するよう、
プログラムを作っていきます。ルール
1利用者が名前とコメントを入力し、発言できる。
2利用者の過去発言内容をデータベースで管理する。
全ての利用者の過去発言を一覧で見ることができ、「名前、コメント、
発言日時」の最低限3つを1行ずつ表示する。
利用者の名前は最大20文字以内とし、それ以上の場合はエラーメッセージを表示し、発言できないようにする。
利用者のコメントは最大100文字以内とし、それ以上の場合はエラーメッセージを表示し、発言できないようにする。
利用者の名前、コメントのどちらか又は両方が未入力だった場合、エラーメッセージを表示し、発言できないようにする。変数設定
$name = ''; //名前 $comment = ''; //コメント $log = date('Y/m/d H:i:s') . "\n"; //年日時 $error = []; //エラーメッセージ $user_data = []; //ユーザーデータ $host = ''; //IPアドレスまたはデータベースのホスト名 $username = ''; //ユーザー名 $passwd = ''; //パスワード $dbname = ''; //データベース名 //データベースの情報を渡して接続する値を$linkに代入する $link = mysqli_connect($host, $username, $passwd, $dbname);mysqli_connect()でデータベースに必要なデータの塊のIDで接続をします。
if($_SERVER['REQUEST_METHOD'] ==='POST') { if(isset($_POST['name']) === true) { $name = $_POST['name']; if(isset($_POST['comment']) === true) { $comment = $_POST['comment'];データの送受信をPOSTを使うときに、その中の値をname,comment
にそれぞれ代入します。$name = str_replace(array(" ", " "), "", $name); $comment = str_replace(array(" ", " "), "", $comment);str_replace()で、空白を入力しただけのデータを送信することを
防いでくれます。エラーの条件を設定
if(mb_strlen($comment) >= 101) { $error[] = '100文字以内にして下さい'; }else if (empty ($comment) === true){ $error[] = 'コメントを入力してください' . "\n"; } if(mb_strlen($name) >= 21) { $error[] = '20文字以内にして下さい'; }else if (empty($name) === true){ $error[] = 'お名前を入力してください' . "\n"; } ```php mb_strlenで文字の長さを出します。strlenは半角英数字を1文字にしていますが、mb_strlenは全角の文字でも1文字としてくれるので使用しています。 ##データベースに接続します カラム名 name,comment,date テーブル名 comment_table ```php if($link) { //接続するときに文字化け防止 mysqli_set_charset($link,'utf8'); //テキストに入力があったとき if(trim($name) !== '' && trim($comment) !== '') { //データベースの実行内容を$queryに代入する $query = 'INSERT INTO comment_table(name,comment,date) VALUE(\''.$name.'\',\''.$comment.'\',\''.$log.'\')';文字列の中に変数を入れる場合\''.$name.'\'と記述します。
$query = "INSERT INTO comment_table(name,comment,date) VALUE('$name','$comment','$log')";SQLの命令文をダブルクォーテーションでくくって、変数を
シングルクォーテーションでくくります。
こちらの記述の方がシンプルで見やすいですね。実行します
mysqli_query($link, $query);過去の発言を見れるようにする
//データベースに入った順番、名前、コメント日付を取得 $query = 'SELECT id,name,comment,date FROM comment_table'; //クエリ実行 $result = mysqli_query($link, $query); //1行ずつ取得 while ($row = mysqli_fetch_array($result)) { $user_data[] = $row; } ```php my_sqli_fetch_array()で取得したデータを1行を$rowに代入し、 それを$user_dataの配列として代入する ```php mysqli_free_result($result); mysqli_close($link); } } else { echo 'DB接続失敗'; }mysqli_free_result()でデータを保存したメモリを開放します。
全コード
<?php $name = ''; $comment = ''; $log = date('Y/m/d H:i:s') . "\n"; $error = []; $user_data = []; $host = ''; $username = ''; $passwd = ''; $dbname = ''; //データベースの情報を渡して接続する値を$linkに代入する $link = mysqli_connect($host, $username, $passwd, $dbname); /*変数が存在するかチェック*/ if($_SERVER['REQUEST_METHOD'] ==='POST') { if(isset($_POST['name']) === true) { $name = $_POST['name']; if(isset($_POST['comment']) === true) { $comment = $_POST['comment']; $name = str_replace(array(" ", " "), "", $name); $comment = str_replace(array(" ", " "), "", $comment); /*エラーの条件*/ if(mb_strlen($comment) >= 101) { $error[] = '100文字以内にして下さい'; }else if (empty ($comment) === true){ $error[] = 'コメントを入力してください' . "\n"; } if(mb_strlen($name) >= 21) { $error[] = '20文字以内にして下さい'; }else if (empty($name) === true){ $error[] = 'お名前を入力してください' . "\n"; } } } } if($link) { mysqli_set_charset($link,'utf8'); if(trim($name) !== '' && trim($comment) !== '') { $query = 'INSERT INTO comment_table(name,comment,date) VALUE(\''.$name.'\',\''.$comment.'\',\''.$log.'\')'; //var_dump($query); $result = mysqli_query($link, $query); //var_dump($result); $query = 'SELECT id,name,comment,date FROM comment_table'; $result = mysqli_query($link, $query); //var_dump($result); while ($row = mysqli_fetch_array($result)) { $user_data[] = $row; } //var_dump($user_data); mysqli_free_result($result); mysqli_close($link); } } else { echo 'DB接続失敗'; } ?> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <!--エラーメッセージ--> <p><?php foreach($error as $key => $string){ print htmlspecialchars($value['string'], ENT_QUOTES, 'UTF-8');$string; } ?> </p> <form method="post" action="./16-11.php"> 名前:<input type="text" name="name" value=""> コメント:<input type="text" name="comment" value=""> <input type="submit" value="送信"> </form> <!--送信後の名前、コメント、時間--> <p><?php if($name === '' || $comment === ''){ print ''; } else { } foreach ($user_data as $read){ print htmlspecialchars(($read['name'] . $read['comment']. $read['date'].),ENT_QUOTES,'UTF-8')"<br>"; } ?> </p> </body> </html>
- 投稿日:2020-03-18T11:05:05+09:00
あれ?foreign keyがつかない。。
mysql> alter table student_course -> add constraint FKq7yw2wg9wlt2cnj480hcdn6dq -> foreign key (student_id) -> references student (id);show create table student_course; | student_course | CREATE TABLE `student_course` ( `student_id` bigint(20) NOT NULL, `course_id` bigint(20) NOT NULL, KEY `FKejrkh4gv8iqgmspsanaji90ws` (`course_id`), KEY `FKq7yw2wg9wlt2cnj480hcdn6dq` (`student_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 |原因 > ストレージエンジンがMySAMになってた
MySAMだとforeign keyがつかないのでInnoDBにする
spring bootの設定
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
- 投稿日:2020-03-18T09:18:23+09:00
DockerのMySQLコンテナが、永遠に再起動を繰り返すエラーの対処法
概要
事象
MySQLが動くDockerコンテナを、docker-composeで立ち上げようとしたところ、コンテナが永遠に再起動を繰り返す事象が起こりました。この問題の解決方法を、ここにメモしておきます。
ちなみに、私はWindows上でDocker Toolboxを用いていた時にこの問題が起こりましたが、それ以外の環境だとこの問題は起こらなさそうです(おそらく)。
docker-compose.ymlの設定
docker-compose.ymlのうち、この問題が起こる部分の設定は以下のようになっています。
db: image: mysql:5.7 volumes: - "/tmp/db/data:/var/lib/mysql" - "./db:/usr/src/db" restart: always environment: MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD MYSQL_DATABASE: $MYSQL_DATABASE MYSQL_USER: $MYSQL_USER MYSQL_PASSWORD: $MYSQL_PASSWORD ports: - 3306:3306特別な設定は何もしておらず、単純に
mysql:5.7
のイメージをベースに必要最低限の設定をしているのみです。対処法
立ち上がったコンテナ内で、
--innodb-use-native-aio=0
を実行させます。なので、docker-compose.ymlは以下のようになります。db: image: mysql:5.7 volumes: - "/tmp/db/data:/var/lib/mysql" - "./db:/usr/src/db" restart: always environment: MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD MYSQL_DATABASE: $MYSQL_DATABASE MYSQL_USER: $MYSQL_USER MYSQL_PASSWORD: $MYSQL_PASSWORD ports: - 3306:3306 command: --innodb-use-native-aio=0 # <- これ!なぜこれで解決するのか
MySQLの公式ドキュメントには、以下のような記述があります。
InnoDB uses the asynchronous I/O subsystem (native AIO) on Linux to perform read-ahead and write requests for data file pages. This behavior is controlled by the innodb_use_native_aio configuration option, which applies to Linux systems only and is enabled by default.
InnoDB(MySQLのためのデータベースエンジン)はデフォルトでLinuxの非同期I/O(native AIO)を用いるように設定されていますが、この挙動は
innodb_use_native_aio
オプションで変更できます。今回私はWindows上でDocker Toolboxを用いてコンテナを動かしていたのですが、その場合だとこの非同期I/Oが利用できないため、エラーが起こり再起動が繰り返されていたようです。そのため、公式ドキュメントの上に引用した部分に書いてある通り、
innodb_use_native_aio
オプションで非同期I/Oを用いないように設定して、この問題を回避する必要があります。
- 投稿日:2020-03-18T09:18:23+09:00
DockerのMySQLコンテナが、Docker Toolbox上で起動に失敗するエラーの対処法
概要
事象
MySQLが動くDockerコンテナを、docker-composeで立ち上げようとしたところ、コンテナが永遠に再起動(restart)を繰り返す事象が起こりました。この問題の解決方法を、ここにメモしておきます。
ちなみに、私はWindows上でDocker Toolboxを用いていた時にこの問題が起こりましたが、それ以外の環境だとこの問題は起こらなさそうです(おそらく)。
docker-compose.ymlの設定
docker-compose.ymlのうち、この問題が起こる部分の設定は以下のようになっています。
db: image: mysql:5.7 volumes: - "/tmp/db/data:/var/lib/mysql" - "./db:/usr/src/db" restart: always environment: MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD MYSQL_DATABASE: $MYSQL_DATABASE MYSQL_USER: $MYSQL_USER MYSQL_PASSWORD: $MYSQL_PASSWORD ports: - 3306:3306特別な設定は何もしておらず、単純に
mysql:5.7
のイメージをベースに必要最低限の設定をしているのみです。対処法
立ち上がったコンテナ内で、
--innodb-use-native-aio=0
を実行させます。なので、docker-compose.ymlは以下のようになります。db: image: mysql:5.7 volumes: - "/tmp/db/data:/var/lib/mysql" - "./db:/usr/src/db" restart: always environment: MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD MYSQL_DATABASE: $MYSQL_DATABASE MYSQL_USER: $MYSQL_USER MYSQL_PASSWORD: $MYSQL_PASSWORD ports: - 3306:3306 command: --innodb-use-native-aio=0 # <- これ!なぜこれで解決するのか
MySQLの公式ドキュメントには、以下のような記述があります。
InnoDB uses the asynchronous I/O subsystem (native AIO) on Linux to perform read-ahead and write requests for data file pages. This behavior is controlled by the innodb_use_native_aio configuration option, which applies to Linux systems only and is enabled by default.
InnoDB(MySQLのためのデータベースエンジン)はデフォルトでLinuxの非同期I/O(native AIO)を用いるように設定されていますが、この挙動は
innodb_use_native_aio
オプションで変更できます。今回私はWindows上でDocker Toolboxを用いてコンテナを動かしていたのですが、その場合だとこの非同期I/Oが利用できないため、エラーが起こり再起動が繰り返されていたようです。そのため、公式ドキュメントの上に引用した部分に書いてある通り、
innodb_use_native_aio
オプションで非同期I/Oを用いないように設定して、この問題を回避する必要があります。コンテナの再起動について
コンテナが再起動するのは、私がdocker-compose.ymlに
restart:always
を書いているからです。それ以外の場合は、普通にコンテナが落ちると思われます。
- 投稿日:2020-03-18T08:54:43+09:00
【自分メモ】MySQLトラブルシューティング
TS01
現象
SQL実行時、以下のエラーが発生。
Syntax error or access violation: 1055 Expression #124 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'カラム名' which is not functionally dependent on columns in GROUP BY clause;this is incompatible with sql_mode=only_full_group_by解決方法
my.cnfに以下を定義する。
my.cnf[mysqld] sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTIONDockerを利用している場合
docker-compose.ymlmysql: image: mysql:5.7 command: mysqld --sql-mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION 〜以下省略〜参考
T02
現象
日本語が文字化けする。
解決方法
my.cnfに以下を定義する。
my.cnf[mysqld] character-set-server=utf8 collation-server=utf8_general_ci [client] default-character-set=utf8Dockerを利用している場合
docker-compose.ymlmysql: image: mysql:5.7 command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci 〜以下省略〜参考
TS03
現象
INSERT、UPDATE時に以下のエラーが発生する。
Incorrect string value: '\xF0\xA6\x9A\xB0\xE7\x94...' for column 'my_column' at row 1解決方法
TS02の対応のみだと、既存テーブルには反映されないので、個別に変更してあげる。
ALTER TABLE <テーブル名> CONVERT TO CHARACTER SET <文字コード>;参考