20201119のMySQLに関する記事は8件です。

RDBで後になって困ったこと3選

その①安直フィールド追加

UserModel
$table = ['id','name', 'email', 'phone'];

例えばusersとかいうテーブルがあるとして、アカウントの基本情報を含めておくときにフィールドとして持たせるのか、user_profileのような子テーブルを作成しそちらにプロフィールや連絡先などの情報を持たせるのか迷う時がある。安直に考えれば、フィールドでいいじゃんとなるが、これに苦しめられた。

苦しむ原因①:フィールドが増えすぎる

後になってこれも必要これも必要という形で追加していくと、どんどんテーブルが肥大化し管理しにくくなる、挙げ句の果てにはジェイウォークとかJsonフィールドとかが出てくるともう触る気が失せる。

苦しむ原因②:単一から複数への仕様変更

もともと、一つの情報しか格納しない予定だったのに、複数情報を格納するように仕様が変更される場合。既存のフィールドの利用をやめ、子テーブルを作成して管理するようになるが、なら元からテーブルを分けておくべき。

苦しむ原因③:使用状況の管理

仕様の変更などで、あるフィールドをもう使わないなどになった時に、フィールドを簡単にドロップさせるのはあまりにもリスキー、IDE等の機能やテストで、落としても大丈夫そうなのは確認できるものの予期せぬ不具合が起こりかねず、起きた時フィールドが落とされていると復旧がめんどくさくなるので使用しなくなったとしても、ある程度の期間フィールドを残したまま様子を見たくなってしまう。(個人の感想)こうなると何時このレコード落としていいのか、誰が落とすのか、どうやって落とすのか、そのフィールドを使わない間どのように対応するのかなど管理するタスクがどっと増えしんどい。

アンチ安直フィールド追加方針

  • 絶対に後になってフィールドが増えない事が保証されている場合にのみフィールドとする
  • 管理する情報が単一から複数に絶対に変更されない事が保証されている場合にのみフィールドとする
  • 該当テーブルにあるフィールドの属性(近しさ)が一致しない場合にはテーブルを極力分けるようにする

上2つは多分基本的なことなのだと思うが、3つめは個人的に思うとこと。卑近な例で言えば従業員テーブルに氏名、メールアドレスなどがあるとして、そこに緊急連絡先も管理するとなった時にフィールド追加せず、テーブルを分ける。従業員に関する情報だけれども属性的には従業員自身が所有するとは言い切れず、緊急連絡先も追加されるとなれば、住所や最寄駅、などなど他の情報を管理する必要も出てくるかもしれないため。これだけわかりやすければいいけど結構微妙なラインに遭遇したため今は迷ったら子テーブル。

その②AUTO INCREMENT PRIMARY KEY

このマスターテーブル作り替える事ないでしょうと思っていたため任意のIDではなく、auto incrementのプライマリキーを使っていたら非常に管理しにくくなってしまった。

苦しむ原因①:繊細な更新

既存のものを更新して、同時に新しいレコードを追加する必要が出たときは最悪。複数のテキストフィールドにwhereで検索をかけて、ある場合にはアプデ、ない場合には作成をしたが、そもそもある程度の長さのあるテキストで検索かける事自体に抵抗があるし、まかり間違って変更対象ではないレコードによきせぬ変更が加えられたら目も当てあられない。
10件とかの本当に極小のカテゴリー用のマスターテーブルとかであれば目視でまあなんとかすることもできるが、CSVから作成するマスターテーブルとなるとかなり精神を削られる更新作業になる。

苦しむ原因②:IDの付け替え

やっぱり後から任意IDで管理したいとなると、当然これまでのプライマリキーから新しく作成したプライマリキーへの移行が必要になる。数多の関連テーブルの内容を一切のミスなく付け替える作業は当然精神が削られる。

アンチAUTO INCREMENT PRIMARY KEY方針

  • マスターテーブルはAUTO INCREMENTであるべき積極的理由がある場合以外には任意IDで管理する

その③INDEXレス スロークエリ

これは比較的軽めだけれど、えこの程度の件数でも必要だったの?!と思うことがあったので事前に知って起きたかった。というか検証しておくべきだった。

勝手に自分の中で100万とかのレコードから検索するならインデックスとかをよく考えて設計する必要があるんだろうなと思っていたら、7万件くらいですでにかなり遅かった。(7万件のレコードのupsertで30分とか)

アンチINDEXレス スロークエリ方針

  • ダミーデータで実行速度を比較しIndexを貼る必要がありそうであれば貼る

まとめ

数ヶ月スパンで過去の自分に首を絞められている気がしている。
レベル感的には、そこでつまづくとかwwwといったレベル感かもしれないけれど、自分への戒めと備忘録として記録。今まさに未来の自分か保守する他人の首を絞めようとしている人への気づきになれば幸い。

皆さんの経験した地獄があれば教えていただけると嬉しいです。

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

Windows10へのMYSQL(Zip版)インストール

アーカイブ入手先

https://dev.mysql.com/downloads/mysql/5.7.html
から。ここでは5.7.32の例で。

インストール

zip解凍して任意の場所に配置。スペースが入ったフォルダでもいいみたいだが、2バイト文字は不可。
ここでは「C:\mysql-5.7.32-winx64」に配置したとして。
配置先直下にmy.iniでファイル新規作成。中身は以下。

[my.ini]
[mysqld]
character-set-server=utf8mb4
collation_server=utf8mb4_general_ci
init-connect='SET NAMES utf8mb4'
skip-character-set-client-handshake
port=3307
character-set-server=utf8mb4
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

[mysqldump]
default-character-set=utf8mb4

[mysql]
default-character-set=utf8mb4

[client]
default-character-set=utf8mb4

コマンドプロンプトを管理者で起動。DB初期化を行う。rootの初期パスワードはログに吐かれるらしいが、Windowsだとどこにログがあるか不明だったので、初期パスワードなしでインストールしその後にパスワードを設定する方法をとった。
配置先直下にdataの名前でフォルダを作る。

> C:\mysql-5.7.32-winx64\bin\mysqld --defaults-file=C:\mysql-5.7.32-winx64\my.ini --initialize-insecure

何も出ずにかえってくれば成功。dataフォルダに何かあるとエラーになるのでその場合は空にして再実行。

サービスに登録する。

> C:\mysql-5.7.32-winx64\bin\mysqld --install MYSQL5_7_32 --defaults-file=C:\mysql-5.7.32-winx64\my.ini
Service successfully installed.

これでサービスダイアログからでも上げ下げできる。
rootのパスワードを設定する。

> C:\mysql-5.7.32-winx64\bin\mysql -u root -P 3307
mysql> alter user root@localhost identified by 'root';
Query OK, 0 rows affected (0.00 sec)

これでrootにもパスワードが設定できた。
あとはA5Mk2などのツールで。

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

入力フォームの情報+複数枚の画像をバイト配列に変換する方法【Servlet/JSP】【MySQL】

1.前提知識・条件

本記事では、Java、Servlet/JSP、MySQLなどの環境構築について、構築できている前提とするので省略します。
Java、Servlet,JSP、MySQLに関する基礎知識を前提としています。
必要となる知識
Java : リスト, イテレータ など
Servlet/JSP : GET/POST, データベースとの通信 など
MySQL : Javaのソース上でクエリを実行する方法 など

注意事項:冗長的なコードになっている可能性があるのでご了承ください。

2.投稿のきっかけ

研修でServlet/JSP、MySQLを使ってWebアプリを構築することになり画像の処理が必要でした。
MySQLの方をMediumBLOB型にして、一枚の画像のみを格納・表示させる所までは、それなりに情報が載っており、比較的容易でした。
ですが、入力フォームのテキスト情報と一緒になった場合、画像を複数枚にした場合に情報が少なく行き着くまでにかなり苦労しました。
自分の備忘録としても、他の方の参考になれば良いかと思います(需要があるかは不明)。

3.画像の保存

大まかな処理の流れは、下図のようになります。
flow1.png
①Webブラウザ(JSPファイル)のフォームに情報・画像を登録
②送信ボタンが押されるとServletに登録情報が送信される
③Servletでデータを取得し、画像データをバイト配列に変換する
④DAOクラスを呼び出し、MySQLへ保存する
※本記事では④の処理を省略しています。

4.テーブル構成

今回は簡単に画像名テーブルと画像テーブルの二つをサンプルとします(省略に省略を重ねています)。
画像を複数枚登録する場合は、画像名:画像 = 1:多になることを想定しています。

画像名テーブル

nameId name
varchar(4) varchar(16)
Primary Key

画像テーブル

nameId imageId image
varchar(4) varchar(4) mediumblob
Primary Key

5.実際のコード

form.jsp
<form action="/test/RegisterServlet" enctype="multipart/form-data" method="post" name="reg" id="regform">
 <div>画像名<input type="text" name="imagename"></div>
 <div class="inputarea">画像
  <input type="file" name="file" id="ItemImage" multiple="multiple" accept="image/*" required >
 </div>
 <input type="submit" value="登録">
</form>

formタグ内でenctype="multipart/form-data"を指定することで、複数のデータ型を扱うことが出来る様になります。

RegisterServlet.java
//送信されてきた情報の取得
Collection<Part> pa = request.getParts();
//画像名用の変数を宣言
String name;


ArrayList<Part> regImg = new ArrayList<Part>();
//画像データをバイト配列に変換したとき用のリスト
ArrayList<byte[]> imgList = new ArrayList<byte[]>();

//拡張for文でCollection<Part>の中身をすべて取り出す
for(Part p : pa) {
 //要素のname属性名が"file"であった場合、画像データ用のリストへ格納
 if(p.getName().equals("file")) {
  regImg.add(p);
  } else {
  //画像以外である場合、nameに値を格納
  name = request.getParameter(p.getName()); // ※1
  }
 }

//画像データ格納用のリストの中身をすべて取り出す
for(Part p : regImg) {
 //FileInputStream型にキャストする
 FileInputStream fis = (FileInputStream) p.getInputStream();
 //readAllBytesメソッドでbyte配列に変換する
 byte[] bytes = fis.readAllBytes();
 //byte配列用のリストに格納する
 imgList.add(bytes);
 }
 //DAOメソッドの呼び出し
}

enctype="multipart/form-data"で送られてきたデータはPart型で送られます。
複数のデータを送った場合は、request.getPartsメソッドでCollection型の変数に格納できます。

※1
今回は画像名だけなのでelse文以下は、「name = request.getParameter(p.getName())」だけになっています。
画像名以外のテキストも登録される場合は、HashMapなどを宣言して(p.getName(), request.getParameter(p.getName())で(name属性, パラメータ)の様にセットで格納しておくとよいでしょう。

6.まとめ

いかがだったでしょうか。
本記事では、ブラウザから送られてきたテキストと画像データをServletで受け取ってバイト配列に変換する方法を記述しました。
バイト配列に変換してしまえばデータベースの登録は比較的容易なので省力しています。
需要あるか分かりませんが、私と同じ事考えていて、困る人が少しでも減ったら幸いです。

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

MySQLのスキーマ定義をBacklog記法に変換する

はじめに

既存データベース(MySQL)のテーブル定義書が必要になったので自動生成する方法を調べてみると MySQL のスキーマ定義を Markdown にして Wiki に貼るという記事を見つけました。ただ、BacklogのWikiに出力したかったので、見つけた記事を参考にBacklog記法へ変換してみました。

Railsなら

とかでも良いかもしれません。(最後のはER図ですが)

xsltprocって何?

xsltproc is a command line tool for applying XSLT stylesheets to XML documents.

xsltproc user manual
xsltprocは、XMLドキュメントにXSLTスタイルシートを適応するためのコマンドラインツールらしいです。
XMLに関連するXSLTというスタイルシートがあるみたいですね。

XMLはデータの論理的な構造を記述するための言語ですから、XMLによって記述されたXML文書(以下XMLデータ)には、それがどんな体裁でWebブラウザや紙などに表示されるべきかを指示するレイアウト情報(スタイル情報)は含まれていません。
(中略)
XMLデータの構造変換を指定する部分を、独立した規格として取り出したのがXSLT(Extensible Stylesheet Language Transformations)です。

XSLTスタイルシートの基礎の基礎:XSLTスタイルシート書き方講座(1) - @IT
読んてみたところXMLを他のフォーマットに変換するために必要みたいですね。XMLをCSVやHTMLなどにも変換が可能なようです。昔はXMLで出力してるの流行ってたな...この記事も2001年のやつか。

手順

1. 必要なコマンドのインストール

$ sudo apt-get install xsltproc

Macとかだとデフォルトで入っているみたいですね。

2. 下記のコードをコピペし、「backlog_style.xsl」を用意します。

backlog_style.xsl
<?xml version="1.0" encoding="utf8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s="http://sqlfairy.sourceforge.net/sqlfairy.xml">
<xsl:output method="text" encoding="utf8"/>
<xsl:template match="database">
#contents
<xsl:apply-templates select="table_structure"/>
</xsl:template>
<xsl:template match="table_structure">
* <xsl:value-of select="@name"/>
|TBL物理名|TBL論理名(コメント)|h
|<xsl:value-of select="@name"/>|<xsl:value-of select="options/@Comment"/>|
- カラム情報
|物理名|データ型|NULL|デフォルト|キー|論理名(コメント)|Extra|h<xsl:apply-templates select="field"/>
- インデックス情報
|インデックス名|カラム|複合キー順序|NULL|UNIQ|h<xsl:apply-templates select="key"/>
</xsl:template>

<xsl:template match="field">
|<xsl:value-of select="@Field"/>|<xsl:value-of select="@Type"/>|<xsl:value-of select="@Null"/>|<xsl:choose><xsl:when test="@Default != ''"><xsl:value-of select="@Default"/></xsl:when><xsl:otherwise>n/a</xsl:otherwise></xsl:choose>|<xsl:choose><xsl:when test="@Key != ''"><xsl:value-of select="@Key"/></xsl:when><xsl:otherwise>n/a</xsl:otherwise></xsl:choose>|<xsl:choose><xsl:when test="@Comment != ''"><xsl:value-of select="@Comment"/></xsl:when><xsl:otherwise>n/a</xsl:otherwise></xsl:choose>|<xsl:choose><xsl:when test="@Extra != ''"><xsl:value-of select="@Extra"/></xsl:when><xsl:otherwise>n/a</xsl:otherwise></xsl:choose>|<xsl:text></xsl:text>
</xsl:template>

<xsl:template match="key">
|<xsl:value-of select="@Key_name"/>|<xsl:value-of select="@Column_name"/>|<xsl:value-of select="@Seq_in_index"/>|<xsl:choose><xsl:when test="@Null != ''"><xsl:value-of select="@Null"/></xsl:when><xsl:otherwise>NO</xsl:otherwise></xsl:choose>|<xsl:choose><xsl:when test="@Non_unique = '0'">YES</xsl:when><xsl:otherwise>NO</xsl:otherwise></xsl:choose>|<xsl:text></xsl:text>
</xsl:template>

</xsl:stylesheet>

3.下記のコマンドを実行します。

# mysqldumpコマンドをつかってXML形式でスキーマ情報を出力
$ mysqldump --no-data --xml app_development -u root -p > app.xml

# xsltprocコマンドをつかってXML形式からBacklog記法のテーブルテキストへ変換。設定ファイルは上記のものを使用。
$ xsltproc -o app.md backlog_style.xsl app.xml

4.下記のようなファイルが作成されます。

app.md
#contents

* schema_migrations
|TBL物理名|TBL論理名(コメント)|h
|schema_migrations||
- カラム情報
|物理名|データ型|NULL|デフォルト|キー|論理名(コメント)|Extra|h
|version|varchar(255)|NO|n/a|PRI|n/a|n/a|
- インデックス情報
|インデックス名|カラム|複合キー順序|NULL|UNIQ|h
|unique_schema_migrations|version|1|NO|YES|

5.上記をBacklogに貼り付け

スクリーンショット 2020-11-20 10.20.40.png

完成!

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

複数のLaravelアプリを任意のデータベースに接続する方法

はじめに

Laravelでの開発で、最初のサンプルアプリはつくってみた。
次は本格的にアプリケーションを作ってみたいけど
最初に使ったDBとは別のDBに接続してテーブル作りたい。
そんな時に試行錯誤した設定方法を備忘録として残します。
誰かの参考になれば幸いです。

*1〜3の手順は初めてLaravelを使用する際にも通る工程です。

開発環境
MAC
VirtualBox
Homestead
vagrant 2.2.9
PHP 7.3.11
Laravel 5.5.48

1.Laravelのダウンロード

composerで新規のLaravelをインストールしていきます。
ターミナルを開いてHomesteadが置いてあるディレクトリまで移動します。
移動したら以下を打ち込んでください。
composer create-project laravel/laravel Laravel_new
Laravel_newの部分はファイル名にあたります。任意のプロジェクトファイル名に変更してください。
ディレクトリ構造は
Laravel
 |- Homestead
 |- Laravel_sample
 |- Laravel_new
となります。

2.Homestead.yamlを編集する

~~省略
folders:
//↓最初に設定したパス
    - map: /Users/ユーザー名/Laravel 
      to: /home/vagrant/code

//↓追加するパス 同じディレクトリなので設定する必要ないかもしれませんが一応いれておきます
    - map: /Users/ユーザー名/Laravel
      to: /home/vagrant/code

sites:
//↓最初に設定したパス
    - map: laravel.sample
      to: /home/vagrant/code/laravel_sample/public

//↓追加するパス
    - map: laravel.new //ドメイン名になる。基本なんでもOKだけど全部小文字で!
      to: /home/vagrant/code/laravel_new/public



databases:
    - homestead
    //↓使用したいデータベース名を設定します。これも何でもOK。2つ目のLaravelアプリで使用するテーブルがこのデータベースに入ります。
    - laraveldb
~~省略

2.hostsファイルにドメインを追加

hostsファイルは自身のPCに最初から入っているファイルです。
「hosts」で検索するとectというフォルダの中に入ってると思います。
先ほどのHomestead.yamlに追加したドメイン名と同じものを、このhostsファイルにも追記します。
必ず半角スペースをあけて追記しましょう。

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1   localhost
255.255.255.255 broadcasthost
::1             localhost
192.168.10.10 laravel.sample laravel.new ←これ

注意点として、このhostsファイルはPC上の大事なファイルなので変更できないようになっています。
一度、デスクトップなどに移動させてから変更し、終わったら元の場所に戻すというやり方で変更できます。

3.envファイルの設定

.envファイルに、今回のlaravel.newで使用するMySQLのデータベースにアクセスできるよう、設定を追加します。

~省略~
↓もともとあったもの
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=***

↓laravel.newのために追加するもの
DB_CONNECTION_NEW=laravelnew
DB_HOST_NEW=127.0.0.1
DB_PORT_NEW=3306
DB_DATABASE_NEW=laraveldb
DB_USERNAME_NEW=root
DB_PASSWORD_NEW=***

~省略~

末尾に追加した_NEWは区別するために加えたものです。
DB_DATABASE_NEWHomestead.yamldatabases:で設定した名前の通り指定します。
usernameとpasswordは自身のものを指定してください。今回は*で伏せています。

4.database.phpの設定

Laravelのセットに入っているdatabase.phpに設定を追記します。
configフォルダに入っています。

 'laravelnew' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST_NEW', '127.0.0.1'),
            'port' => env('DB_PORT_NEW', '3306'),
            'database' => env('DB_DATABASE_NEW', 'laraveldb'),
            'username' => env('DB_USERNAME_NEW', 'root'),
            'password' => env('DB_PASSWORD_NEW', '***'),
            'unix_socket' => env('DB_SOCKET_NEW', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],

変更箇所のみ抜粋しています。
追記が終わったら、一番上のdefaultも変更しておきましょう。
laravelnewとは、前工程で編集したenvファイルのDB_CONNECTION_NEWに設定したものです。

'default' => env('DB_CONNECTION_NEW', 'laravelnew'),

DB_CONNECTION名は、「この設定で指定した通りのものを使います!」という合言葉のようなもの(と認識しております。)です。違ったらご指摘いただけると幸いです…。
例えば、この先シーディングファイルにテーブルの初期値を入れることになるかと思いますが、その時に
DB::connection('laravelnew')->table('users')->insert([...])とすると、database.phpに追記したデータベースに入れてくれます。
(defaultに設定しておけばこの手順は省けるはずなんですが、なぜか私の場合は使いたいデータベースに接続できず、最初に使用していたデータベースにシーディングされてしまいました…)

5.設定の反映

ここまでできたら、今までの設定を反映させます。
database.phpなどの設定ファイルをいじった後は仮想OSを再起動しないと反映されません!
vagrant reload --provisionをターミナルに打ち込んでください。

6.最終確認

これで設定は完了したはずですが、このまますぐにmaigrateしたりseedするのはちょっと怖いので
本当に設定できているか確認しましょう。
tinkerを使います。
vagrant sshでssh接続します。
cdで自身のプロジェクトファイルまで潜って(今回はlaravel_new)
php artisan tinkerと叩きます。
以下は実行した処理内容です。

vagrant@homestead:~/code/laravel_new $ php artisan tinker
Psy Shell v0.9.12 (PHP 7.4.5 — cli) by Justin Hileman
>>> config('database.default')
=> "laravelnew"
>>> config('database.connections.laravelnew')
=> [
     "driver" => "mysql",
     "host" => "127.0.0.1",
     "port" => "3306",
     "database" => "laraveldb",
     "username" => "root",
     "password" => "***",
     "unix_socket" => "",
     "charset" => "utf8mb4",
     "collation" => "utf8mb4_unicode_ci",
     "prefix" => "",
     "strict" => true,
     "engine" => null,
   ]
>>> 

config('database.default')でdatabase.phpでデフォルトに設定したコネクション名がでてきます。
次に、config('database.connections.laravelnew')で、database.phpに設定した内容が走ります。

これで先ほど設定した内容がうまいこといってることが確認できました!
安心してマイグレーション、シーディングができますね。

ちなみに実際にマイグレーションするときに
php artisan migrate --database=laravelnew
とすると確実にlaravelnewで使用したいデータベースに接続できるはずです。心配な方はやってみるといいと思います!


以上で任意のデータベースに接続する方法は終了です。
次回はできあがったアプリをHerokuにデプロイするまでの工程を記事にしたいと思います!

この記事の内容に、間違っている点、もっとこうした方がいいという点などありましたらコメントいただけると幸いです。

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

MySQLのmysqld --initialize-insecureでos_file_get_status() failedが発生する場合の対処

概要

mysqld --initialize-insecureos_file_get_status() failed が発生する場合の対処方法.

事象

以下のようなエラーが発生

# mysqld --initialize-insecure

2020-11-19T15:06:42.270143+09:00 0 [ERROR] InnoDB: Operating system error number 13 in a file operation.
2020-11-19T15:06:42.270179+09:00 0 [ERROR] InnoDB: The error means mysqld does not have the access rights to the directory.
2020-11-19T15:06:42.270186+09:00 0 [ERROR] InnoDB: os_file_get_status() failed on './ibdata1'. Can't determine file permissions
2020-11-19T15:06:42.270194+09:00 0 [ERROR] InnoDB: Plugin initialization aborted with error Generic error

確認したこと

The error means mysqld does not have the access rights to the directory

から,データディレクトリ( /var/lib/mysql )の権限がいけないのか?と考え確認するも, 750 で問題なし.

結論

結局,SELinuxで引っかかっていた
当処理を実行する際のみ setenforce 0permissive にすることで,当該エラーは出ず問題なくinitializeが実行された.

audit.log

ガッツリdenyされていますね...:cop:

/var/log/audit/audit.log
type=AVC msg=audit(******): avc:  denied  { getattr } for  pid=1951 comm="mysqld" path="/var/lib/mysql/ibdata1" dev="dm-0" ino=****** scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:var_lib_t:s0 tclass=file permissive=1
type=AVC msg=audit(******): avc:  denied  { open } for  pid=1951 comm="mysqld" path="/var/lib/mysql/ibdata1" dev="dm-0" ino=****** scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:var_lib_t:s0 tclass=file permissive=1
type=AVC msg=audit(******): avc:  denied  { lock } for  pid=1951 comm="mysqld" path="/var/lib/mysql/ibdata1" dev="dm-0" ino=****** scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:var_lib_t:s0 tclass=file permissive=1
type=AVC msg=audit(******): avc:  denied  { ioctl } for  pid=1951 comm="mysqld" path="/var/lib/mysql/ibdata1" dev="dm-0" ino=****** ioctlcmd=9502 scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:var_lib_t:s0 tclass=file permissive=1

以上です.

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

can't connect to local mysql server through socket '/tmp/mysql.sock' (2) への対処

docker-compose上でrailsとmysqlを使ったwebアプリケーションをherokuを利用してデプロイする時にはまったエラーへのアプローチを忘れないための備忘録。

なお、heroku はターミナル からの操作ではなく、heroku のwebサイト上で操作する。

エラーではsocketである'/tmp/mysql.sock'が見つからないと言われているが、明らかに存在しているし、gitignoreにも入ってはいない。

念のため、rails側でのデータベースの設定として、これが必須かは分からないが、下記のsocket:の部分を追記した。

database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: 
  host: localhost
  socket: /tmp/mysql.sock ←ここ

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

production:
  <<: *default
  database: myapp_production
  username: myapp
  password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>

だとしたら、heroku側での設定が間違えていると思いdbと接続するのに必要なherokuの環境変数をいじってみることにする。

これにいいヒントをくれたのが
https://xyk.hatenablog.com/entry/2014/09/29/184727
の記事である。

ただし、今回はターミナル上からではなく、herokuのwebサイト上から操作する必要がある。ターミナルからの操作もやってしまってめちゃくちゃになってしまったので、ここで闇雲に記事通りに進めればいいということでもないと学んだ、、、

まず、herokuのwebサイト上からそもそもcleardbのダウンロード、インストールをしなければいけない。

これは、herokuのサイト上のResourcesのadd-onsから探してあげれば良い。

4E2D0806-FF15-4940-8164-409484F0A3F6_1_105_c.jpeg

次に上記画像のcleardb_database_url と database_url(多分最初はないから作る) の部分をそれぞれ自分の場合 mysql2 を使用しているのでそのように変更する。valuesの部分はcleardb_database_urlの場合はadd-onでインストールした時に自動的にできている。database_urlの場合はcleardb_database_urlのものをコピペしてあげれば良い。

これでできた。

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

MYSQL_データベース作り直す手順

肥大化問題

1. データベースのバックアップを取得
  E:\MySQL\bin\mysqldump.exe -u root -prootpw my_db > E:\dumps\dump.sql

2. MySQLサービスの停止
3. my.iniファイルの設定(保存場所:E:\MySQL\my.ini)
  my.iniを開き、[mysqld]の下に下記の設定を追加
  ********************************************
  # File-Per-Table モードの有効化
  innodb_file_per_table=1
  #ibdata1ファイルの上限を1Gに設定
  innodb_data_file_path = ibdata1:1G
  ********************************************
  この設定により、データベースの保存はibdata1への共有保存からテーブルごとの保存に変更されます。
  すでに変更された場合は、手順3をスキップしてください。

4. ibdata1、ib_logfile0、ib_logfile1を削除(保存場所:E:\MySQL\data\ibdata1)
5. MySQLサービスの再開
6. バックアップからのリストア
  E:\MySQL\bin\mysql.exe -u root -prootpw my_db < "E:\dumps\dump.sql"

DB保存場所をCドライブからEドライブに変更

1. MySQLサービスの停止
2. my.iniファイルの設定(保存場所:E:\MySQL\my.ini)
  my.iniを開き、[mysqld]の下に下記の設定を変更
  ********************************************
  #Path to the database root
  #datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
  datadir="E:/MySQL/Data/"
  ********************************************
4. "C:/ProgramData/MySQL/MySQL Server 5.5/Data/"のデータをすべて"E:/MySQL/Data/"にコピー
5. MySQLサービスの再開

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