tag:crieit.net,2005:https://crieit.net/tags/MariaDB/feed
「MariaDB」の記事 - Crieit
Crieitでタグ「MariaDB」に投稿された最近の記事
2021-11-23T01:20:11+09:00
https://crieit.net/tags/MariaDB/feed
tag:crieit.net,2005:PublicArticle/17774
2021-11-22T02:31:55+09:00
2021-11-23T01:20:11+09:00
https://crieit.net/posts/d5ca0b7ff1f49b32066b352d05c4d40b
匿名掲示板作ってみた
<p>匿名掲示板を作り、アルファ版として公開してみました。<br />
Crieitユーザーの皆さんにもぜひご意見いただきたいです。</p>
<p> -‐ '´ ̄ ̄`ヽ、へ /\<br />
/ /" `ヽ ヽ  ̄  ̄ ̄ ̄ ><br />
//, '/ ヽハ 、 ヽ ̄  ̄>/<br />
〃 {<em>{⌒ ⌒リ| l │ i| / /<br />
レ!小l● ● 从 |、i| / <br />
ヽ|l⊃ 、</em>,、<em>, ⊂⊃ |ノ│|___</em>__/<br />
/⌒ヽ<strong>|ヘ ゝ._) j /⌒i !<br />
\ /:::::| l>,、 __, イァ/ /│<br />
. /:::::/| | ヾ:::|三/::{ヘ、</strong>∧ |<br />
`ヽ< | | ヾ∨:::/ヾ:::彡' |</p>
<p>その名も、「よろずネットワーク」です。<br />
作った目的は、「世の中のトレンドがわかって」「自由でゆるくて」「ネットの面白かった時代を再現できるような」掲示板を作りたいと思ったことです。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://www.yorozu.network">よろずネットワーク</a></p>
<p>ちなみに、よろずネットワークではAAを綺麗に投稿できます。<br />
<a href="https://crieit.now.sh/upload_images/b211ec485fd073472cd23c247404335f619a810ec0487.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/b211ec485fd073472cd23c247404335f619a810ec0487.png?mw=700" alt="image.png" /></a></p>
<p>コメント欄はこんな感じです。<br />
<a href="https://crieit.now.sh/upload_images/b211ec485fd073472cd23c247404335f619a81667ab12.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/b211ec485fd073472cd23c247404335f619a81667ab12.png?mw=700" alt="image.png" /></a></p>
<p>スレにはyoutube動画やニコニコ動画も貼り付けできます。<br />
<a href="https://crieit.now.sh/upload_images/b211ec485fd073472cd23c247404335f619a818d09a67.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/b211ec485fd073472cd23c247404335f619a818d09a67.png?mw=700" alt="image.png" /></a></p>
<p><strong>技術スタック</strong><br />
サーバー:Conoha VPS(ubuntu 20.04LTS) ×複数<br />
DB: Mariadb on Conoha<br />
バックエンドAPI:Django Rest Framework<br />
フロントエンド: Quasar(Nuxtjsみたいなやつ) でSSR(PWAモード)<br />
ドメイン:google domain<br />
CI/CD:github actions</p>
<p>毎日アバター画像が自動生成されたり、返信がくると通知が来たり、カテゴリごとに毎時ランキングを見られたりなど、掲示板として使いやすいものを意識して作ったので、是非遊びに来てみてください!</p>
<p> <a target="_blank" rel="nofollow noopener" href="https://www.yorozu.network">よろずネットワーク</a></p>
Y O
tag:crieit.net,2005:PublicArticle/15812
2020-04-06T06:18:12+09:00
2020-04-06T19:55:49+09:00
https://crieit.net/posts/MariaDB-MySQL-innodb
MariaDB (MySQL innoDB) が急にダウンする際に行ったパラメーターチューニング
<h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1>
<p>処理が遅いアプリの改善を行った後、処理性能が改善されたものの、MariaDB が急に落ちる問題が頻発。<br />
落ちるたびにシステムが停止し悩まされたが、なんとか解決したので備忘録。</p>
<h1 id="結論"><a href="#%E7%B5%90%E8%AB%96">結論</a></h1>
<ul>
<li>アプリ側で処理数が上昇した事で、IO 負荷が高くなっていた事が根本原因。</li>
<li>ストレージの IOPS を考慮して innodb_io_capacity, innodb_io_capacity_max, innodb_read_io_threads, innodb_write_io_threads を可能な限り増やす。増やすと上昇値が平準化される。負荷が上がり innodb_log_file_size の上限を超えて落ちることが無くなる。</li>
<li>innodb_buffer_pool_size は可能な限り上げる。余裕を持たせ処理を平準化させる。</li>
<li>innodb_log_buffer_size も一定水準まで上げる。上の対処を行った場合でも、負荷が上昇するとこの数値次第で落ちる原因になる。</li>
</ul>
<h1 id="環境"><a href="#%E7%92%B0%E5%A2%83">環境</a></h1>
<div class="table-responsive"><table>
<thead>
<tr>
<th>項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>筐体・メモリ</td>
<td>さくらVPS 16GB</td>
</tr>
<tr>
<td>ストレージ</td>
<td>SSD</td>
</tr>
<tr>
<td>用途</td>
<td>nginx PHP ウェブサーバー + DB サーバー</td>
</tr>
</tbody>
</table></div>
<h1 id="具体的な my.ini 設定値 (関連値含む)"><a href="#%E5%85%B7%E4%BD%93%E7%9A%84%E3%81%AA+my.ini+%E8%A8%AD%E5%AE%9A%E5%80%A4+%28%E9%96%A2%E9%80%A3%E5%80%A4%E5%90%AB%E3%82%80%29">具体的な my.ini 設定値 (関連値含む)</a></h1>
<pre><code>innodb_io_capacity = 2000
innodb_io_capacity_max = 4000
innodb_read_io_threads = 12
innodb_write_io_threads = 12
innodb_buffer_pool_size = 6144M
innodb_log_buffer_size = 250M
innodb_buffer_pool_instances = 4
innodb_flush_method = O_DIRECT
innodb_checksum_algorithm = CRC32
innodb_change_buffer_max_size = 10
innodb_log_file_size = 256M
innodb_log_files_in_group = 2
innodb_lock_wait_timeout = 10
innodb_lru_scan_depth = 1024
innodb_flush_neighbors = 0
innodb_read_ahead_threshold = 0
</code></pre>
<h1 id="経緯や補足など"><a href="#%E7%B5%8C%E7%B7%AF%E3%82%84%E8%A3%9C%E8%B6%B3%E3%81%AA%E3%81%A9">経緯や補足など</a></h1>
<ul>
<li>特定の処理タイミングでのみ落ちていた為、アプリ側の問題を疑ったが、単純な参照と更新を繰り返すだけの処理な為、アプリ側の問題はほぼなかった。</li>
<li>MariaDB そのものについての情報が少ない。MySQL の情報はそこそこある為、適宜参考にする。</li>
<li>用いている MariaDB 10 は MySQL 5.6, 5.7 両バージョンをベースとしたキメラで若干ややこしい。</li>
<li>監視ツールの <a target="_blank" rel="nofollow noopener" href="https://soudai.hatenablog.com/entry/innodb">Mackerel の MySQL プラグイン</a>が役立った。知識がなくとも何かが制限を超えたような事が見て取れるので当たりが付けられた。</li>
<li>innoDB Checkpoint Age (Uncheckpointed) が急激に上昇し MariaDB が落ちていた。当初は innodb_log_file_size を上げて解決を図った。</li>
<li>多少ライフタイムが伸びたが、問題の根本は IO パフォーマンスにある為、上記は本質的な解決策にならず同様の問題が発生していた。</li>
<li>IO パフォーマンスはあくまで設定次第であり、物理側の IOPS に併せて勝手にスケーリングされる訳ではない。</li>
<li>ストレージが HDD では対処不能だったので SSD で助かった。</li>
<li>上記パラメーターが最善値であるか不明。安定し始めてから1週間程度な為、再調整の可能性あり。</li>
</ul>
<h1 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h1>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://www.infiniteloop.co.jp/blog/2013/08/mysql-tuning-cacti-system/">これだけ見れば大丈夫!ーMySQLパフォーマンス監視のツボ(システム編) | 株式会社インフィニットループ技術ブログ</a></li>
<li><a target="_blank" rel="nofollow noopener" href="http://hiroi10.hatenablog.com/entry/20151210/1449731029">MySQL関連のパラメータ(主にInnoDB)について - hiroi10のブログ</a></li>
<li><a target="_blank" rel="nofollow noopener" href="ashitanosora.doorblog.jp/archives/37138751.html">MySQLのIOキャパシティについて : しがないエンジニアのつぶやき</a></li>
</ul>
sola
tag:crieit.net,2005:PublicArticle/15627
2019-12-20T16:47:14+09:00
2019-12-20T17:17:45+09:00
https://crieit.net/posts/MinQ-6-Go
MinQ開発日記 (6) ローカルのGoの開発環境の構築とスキーマ・マイグレーション
<h1 id="Echoによるエコー・サーバー"><a href="#Echo%E3%81%AB%E3%82%88%E3%82%8B%E3%82%A8%E3%82%B3%E3%83%BC%E3%83%BB%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC">Echoによるエコー・サーバー</a></h1>
<p>とりあえずEchoサーバーを立てる. またローカルに開発環境を構築していなかったことを思い出す. やり方は<a href="https://crieit.net/posts/MinQ-3-Docker-Go">MinQ開発日記 (3) Docker上にGo開発環境を構築</a>と同じと思ったのですがGo Modulesというのがあるようです.</p>
<h2 id="構成"><a href="#%E6%A7%8B%E6%88%90">構成</a></h2>
<ul>
<li>Echo (Webサーバー兼アプリケーション)</li>
<li>MariaDB Docker Container</li>
<li>React (認証画面とCRUDインターフェース)</li>
</ul>
<h2 id="goenvとGo Modules"><a href="#goenv%E3%81%A8Go+Modules">goenvとGo Modules</a></h2>
<p>Goのバージョン1.13以降は何もしなくてもGo Modulesが使えるようです.</p>
<p>その前にGoのバージョン管理ができるようにしましょう. pyenvやnodeenvのようにgoenvというのがあります. 公式の<a target="_blank" rel="nofollow noopener" href="https://github.com/syndbg/goenv/blob/master/INSTALL.md">Installation</a>ガイドを読むと大体わかります. GOENV_ROOTがgoenvバイナリのロケーションです.</p>
<pre><code class="bash">export GOENV_ROOT="$HOME/.goenv"
export PATH="$GOENV_ROOT/bin:$PATH"
eval "$(goenv init -)"
export GOPATH="$HOME/go"
export PATH="$PATH:$GOPATH/bin"
</code></pre>
<p>goenvでインストール可能なバージョンを列挙するには以下のようにします.</p>
<pre><code class="bash">goenv install -
</code></pre>
<p>バージョンがずらっと並ぶので, この中から一つ選んでインストールします. 最新版(2019/12/14時点)である1.13.4をインストールします.</p>
<pre><code class="bash">goenv install 1.13.4
goenv global 1.13.4
</code></pre>
<p>これでgoのバージョンは1.13.4です. Go Modulesは好きなところにフォルダを作れます.</p>
<pre><code class="bash">cd ~/your_folder
mkdir minq && cd minq
go mod init
</code></pre>
<p>これでgo.modというファイルができました. 適当にserver.goというファイルを作ります(多分main.goの方が良い気もする).</p>
<pre><code class="go">package main
import (
"net/http"
"github.com/labstack/echo"
)
func main() {
e := echo.New()
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
e.Logger.Fatal(e.Start(":1323"))
}
</code></pre>
<p>minqフォルダ内部で以下を実行すると必要なパッケージ(例えばecho)なんかを勝手にダウンロードしてきて, ビルドしてくれます.</p>
<pre><code class="bash">go build
</code></pre>
<p>minqフォルダの生成物はフォルダ名と同じになるのでこの場合はminqです.</p>
<pre><code class="bash">./minq
</code></pre>
<p>サーバーが起動したらオッケーです. 特別依存性を指定しなくてもimportから解決してくれるっぽいのは良いですが, 反面githubのレポジトリを直接指定する必要があるのは少し面倒でもあります.</p>
<h2 id="MariaDB"><a href="#MariaDB">MariaDB</a></h2>
<p>brewで入れます.</p>
<pre><code class="bash">brew install mariadb
</code></pre>
<p>起動もbrewを使います.</p>
<pre><code class="bash">brew services start mariadb
</code></pre>
<p>起動したデータベースへアクセスします.</p>
<pre><code class="bash">sudo mariadb -uroot
</code></pre>
<h3 id="GORMで必要になる情報"><a href="#GORM%E3%81%A7%E5%BF%85%E8%A6%81%E3%81%AB%E3%81%AA%E3%82%8B%E6%83%85%E5%A0%B1">GORMで必要になる情報</a></h3>
<p>GORMからMariaDBにアクセスするには以下の情報が必要になります.</p>
<ul>
<li>username</li>
<li>password</li>
<li>IPアドレス/ホスト名</li>
<li>ポート番号</li>
<li>データベース名</li>
</ul>
<h4 id="username & password"><a href="#username+%26amp%3B+password">username & password</a></h4>
<p>上の例でmysqlというデータベースがあると思います. このデータベースにuserというテーブルがあります.</p>
<pre><code class="SQL">SELECT user FROM mysql.user;
</code></pre>
<p>名前が被らないように, ここに新しいユーザーを登録します. <a target="_blank" rel="nofollow noopener" href="https://mariadb.com/kb/en/library/create-user/">CREATE USER</a>を使います.</p>
<pre><code class="SQL">CREATE USER 'new_name'@'localhost' IDENTIFIED BY 'your_password';
</code></pre>
<p>new_nameというユーザーにyour_passwordでアクセスできます. ホストはlocalhostです.</p>
<h4 id="ポート番号"><a href="#%E3%83%9D%E3%83%BC%E3%83%88%E7%95%AA%E5%8F%B7">ポート番号</a></h4>
<p>システム変数を指定すると以下のように表示できるようです.</p>
<pre><code class="bash">show variables like 'port';
</code></pre>
<p><a target="_blank" rel="nofollow noopener" href="https://mariadb.com/kb/en/library/show-variables/">SHOW VARIABLES</a><br />
<a target="_blank" rel="nofollow noopener" href="https://mariadb.com/kb/en/library/server-system-variables/#port">port</a></p>
<p>ちなみに私の環境では3306でした(多分誰でも同じ).</p>
<h4 id="データベース名"><a href="#%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E5%90%8D">データベース名</a></h4>
<p>MariaDBがアクセスしたユーザー用に管理してるデータベースを表示するのは簡単です.</p>
<pre><code class="bash">SHOW DATABASES;
</code></pre>
<p>testというテスト用のデータベースが存在するはずです. とりあえずこれを使います.</p>
<pre><code class="SQL">USE test;
</code></pre>
<p>これでデータベースがtestに切り替わります. 後でGOMRでちゃんとスキーマが設定できたかを確認しましょう.</p>
<h2 id="GORM"><a href="#GORM">GORM</a></h2>
<p>GORMでtestデータベースにアクセスしてみましょう. ハンドラを作っておきます. ステータス・コードなんかは現状適当です(DBサーバーでエラーが出たらどうしたら良いのかわからないので).</p>
<pre><code class="go">func accessDB(context echo.Context) error {
db, err := gorm.Open("mysql", "root:@(127.0.0.1:3306)/test?charset=utf8&parseTime=true")
defer db.Close()
if err != nil {
return context.String(http.StatusOK, err.Error())
}
return context.String(http.StatusOK, "Connect to DB")
}
</code></pre>
<p>この時点では以下のようなエラーが出力されます. これはrootユーザーでアクセスする場合sudoer出ないと実行できないからのようです.</p>
<pre><code class="bash">Error 1698: Access denied for user 'root'@'localhost'
</code></pre>
<p><a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/37239970/connect-to-mysql-server-without-sudo">Connect to mysql server without sudo</a></p>
<p>ここで上で作ったnew_nameユーザーを使いましょう(名前は適宜読み替えてください). testというデータベースがデフォルトで存在するはずなのでそれを指定しましょう.</p>
<pre><code class="go">db, err := gorm.Open("mysql", "new_name:@(localhost:3306)/test?charset=utf8&parseTime=true")
</code></pre>
<p>該当箇所を変更してビルド&リスタートするとConnect to DBと表示されるはずです(末尾のクエリ文字列的なのは一旦無視します).</p>
<pre><code class="go">e.GET("/v1/example/mariadb", accessDB)
</code></pre>
<h3 id="スキーマ・マイグレーション"><a href="#%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%9E%E3%83%BB%E3%83%9E%E3%82%A4%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3">スキーマ・マイグレーション</a></h3>
<p>データベースのスキーマの更新を行う作業をスキーマ・マイグレーション, あるいは単にマイグレーションと言うようです. ORM(Object Relational Mapping/Mapper)ではオブジェクト(Goの構造体)のフィールドからスキーマを決めるようです. つまり個々のテーブル上のレコードと構造体のインスタンスが対応関係にあるわけです.</p>
<pre><code class="go">type User struct {
ID int
Name string
}
</code></pre>
<p>テーブル名は自動的に雛形となる構造体名の複数形になります. この場合だとusersというテーブルがtestデータベースに追加されます.</p>
<pre><code class="go"><br />if db.HasTable("users") {
return context.JSON(http.StatusCreated, "User table is already existed")
}
db.AutoMigrate(&User{})
return context.JSON(http.StatusCreated, "Create users table")
</code></pre>
<p>適当なハンドラ関数を作って, エンドポイントに紐付けます. MariaDBに戻って以下を実行します.</p>
<pre><code class="SQL">SHOW COLUMNS FROM users;
</code></pre>
<p>これでusersの構造が表示されるはずです.</p>
<h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2>
<p>EchoからGORMを通じてMariaDBにアクセスすることができました. GORMのチュートリアルでは利用するデータベースの操作には慣れている前提なのか少しつまづきました.</p>
<h2 id="今後"><a href="#%E4%BB%8A%E5%BE%8C">今後</a></h2>
<h3 id="React"><a href="#React">React</a></h3>
<p>データベースを管理するCRUD用のインターフェースを作ります. <a target="_blank" rel="nofollow noopener" href="https://jaredpalmer.com/formik/docs/overview">formik</a>や<a target="_blank" rel="nofollow noopener" href="https://draftjs.org/">Draft.js</a>を使います. これはできたらPWA(Chrome Desktop)にしてネイティブ・アプリのように実行できるようにしたいです. 詳細に踏み込みたくないのでcreate-react-appを使います. またテストにはCypress.jsを使ってみたいです.</p>
<h3 id="認証"><a href="#%E8%AA%8D%E8%A8%BC">認証</a></h3>
<p>現状他の人は使わない前提なので, 実験的にWebAuthenticationを使おうと思っています.</p>
<h3 id="Gitの導入"><a href="#Git%E3%81%AE%E5%B0%8E%E5%85%A5">Gitの導入</a></h3>
<p>プロジェクトはバージョン管理をするのですが, このままだとgom.Openに指定したデータベースのパスワードが丸見えです. 色々方法があるようです. 最初はコマンドライン引数で渡せばいいのかと思ったのですが, Stackoverflowで質問してみるとダメだそうです. コマンドラインにセンシティブなデータを渡すことがそもそもタブーのようです.</p>
<p><a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/59390753/what-is-a-standard-way-to-specify-password-for-mariadb-in-an-api-server">What is a standard way to specify password for MariaDB in an API server?</a></p>
<h4 id="じゃあどうするのか?"><a href="#%E3%81%98%E3%82%83%E3%81%82%E3%81%A9%E3%81%86%E3%81%99%E3%82%8B%E3%81%AE%E3%81%8B%3F">じゃあどうするのか?</a></h4>
<p>まずそもそも構成ファイルをgitの管理下に置かないという手があります(.gitignore). あるいは構成ファイルに.exampleのような拡張子を付け適当なパスワードを入れて本番用とは切り分けるやり方です.</p>
<p><a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/a/2397905/12036118">What is the best practice for dealing with passwords in git repositories?</a></p>
<p>ただこの方法はどちらかというとプロジェクト・テンプレートを公開するような用途に使った方がいい気もします. どちらの方法も認証情報は別の方法で管理する必要があります.</p>
<p>もう一つは<a target="_blank" rel="nofollow noopener" href="https://www.vaultproject.io/">Vault</a>というソフトウェアを使う方法ですが, こちらはかなり大げさなようです.</p>
<p><a target="_blank" rel="nofollow noopener" href="https://opensource.com/article/19/2/secrets-management-tools-git">4 secrets management tools for Git encryption</a></p>
<p>今回は<a target="_blank" rel="nofollow noopener" href="https://www.agwa.name/projects/git-crypt/">git-crypt</a>や<a target="_blank" rel="nofollow noopener" href="https://git-secret.io/">git-secret</a>というのがあるようでこの辺を調べてみようと思います.</p>
<p><a target="_blank" rel="nofollow noopener" href="https://techblog.bozho.net/storing-encrypted-credentials-in-git/">STORING ENCRYPTED CREDENTIALS IN GIT</a><br />
<a target="_blank" rel="nofollow noopener" href="https://qiita.com/daisukeoda/items/c6b6c36009fa3409dc39">本番用の.envを外部に一切知られずに安全にgithubで保存する方法</a><br />
<a target="_blank" rel="nofollow noopener" href="https://qiita.com/jqtype/items/9b0524baa4b7fe6dbde0">Gitリポジトリ暗号化のススメ - git-secret -<br />
Git</a></p>
<h2 id="Reference"><a href="#Reference">Reference</a></h2>
<p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/seicode/items/9ffce10086f0646379a1">【Go】goenvを使ってGo1.13.4の環境構築</a><br />
<a target="_blank" rel="nofollow noopener" href="https://tech.opst.co.jp/2019/07/09/go-modulesも触れてみるgo入門/">Go Modulesも触れてみるGo入門</a><br />
<a target="_blank" rel="nofollow noopener" href="https://qiita.com/gorilla0513/items/27cd34433a48fc8b65db">Go言語のGORMを使ってみた①</a><br />
<a target="_blank" rel="nofollow noopener" href="http://psychedelicnekopunch.com/archives/639">Golang + GORM + MySQL でデータをやりとりする</a></p>
ブレイン
tag:crieit.net,2005:PublicArticle/15600
2019-12-12T21:21:54+09:00
2019-12-12T21:21:54+09:00
https://crieit.net/posts/MinQ-5-MinQ
MinQ開発日記 (5) MinQが目指すもの & テーブル設計
<h1 id="MinQとは何なのかを考える"><a href="#MinQ%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%AA%E3%81%AE%E3%81%8B%E3%82%92%E8%80%83%E3%81%88%E3%82%8B">MinQとは何なのかを考える</a></h1>
<h2 id="動機"><a href="#%E5%8B%95%E6%A9%9F">動機</a></h2>
<p>勉強がてら適当に作っていたAPIサーバー. このデータベースのテーブル設計を考え始めたらどんなデータを収めるべきなのかを考える必要が出てきた. めんどくさいわけだが, これはMinQを具体的に掘り下げるのにいい機会にもなると思った.</p>
<h2 id="MinQを作ろうと思った理由"><a href="#MinQ%E3%82%92%E4%BD%9C%E3%82%8D%E3%81%86%E3%81%A8%E6%80%9D%E3%81%A3%E3%81%9F%E7%90%86%E7%94%B1">MinQを作ろうと思った理由</a></h2>
<p>基本的には勉強履歴を付けようと思ったからです. ただそのためのルールとかサービスで自分に合うものがなかった(見つけられなかった)のでポートフォリオがわりになるかと思って作り始めました.</p>
<h2 id="より良い勉強法とは?"><a href="#%E3%82%88%E3%82%8A%E8%89%AF%E3%81%84%E5%8B%89%E5%BC%B7%E6%B3%95%E3%81%A8%E3%81%AF%3F">より良い勉強法とは?</a></h2>
<p>勉強に王道はないとよく言われる. 特に楽な方法はないとされます(<a target="_blank" rel="nofollow noopener" href="https://wired.jp/2014/08/15/learn-languages-while-sleeping/">睡眠学習にも一定の効果があると言う話もある</a>という話もありますが・・・). 反復学習が必要でモノの本には脳に汗をかかせることが大事と言う趣旨のことが書いてあった記憶があります. とはいえ闇雲にやっても暗中模索で, 迷子になるのがオチだし, 忘却曲線のように効果がある勉強法もいくつか存在するのは確かです. アウトプットが良いなんて話もあって, 勉強したことをブログに書くと言うこともあるだろう. 備忘録にもなるので設定や環境構築なんかではやる人も多いわけですが, 実際はググった方が速かったりします.</p>
<h2 id="勉強法"><a href="#%E5%8B%89%E5%BC%B7%E6%B3%95">勉強法</a></h2>
<p>いち初学者として自分が勉強する上でどうやれば良いのかを考えた. また教育系の一般書に目を通して比較的効率的な学習法も調べた. その結果現状あまり良い勉強法と言うか環境が提供されていない気がした.</p>
<div class="table-responsive"><table>
<thead>
<tr>
<th align="center">勉強法</th>
<th align="center">利点</th>
<th align="center">弱点</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">アウトプット</td>
<td align="center">情報を共有できる</td>
<td align="center">グーグル検索問題</td>
</tr>
<tr>
<td align="center">動画</td>
<td align="center">分かりやすい</td>
<td align="center">効率がいまいち</td>
</tr>
<tr>
<td align="center">文章チュートリアル</td>
<td align="center">分かりやすい. 動画よりは効率的</td>
<td align="center">探すのが辛い</td>
</tr>
<tr>
<td align="center">スクール</td>
<td align="center">ピア・プレッシャでモチベーションを維持できる</td>
<td align="center">高額, 初心者向けしかない</td>
</tr>
<tr>
<td align="center">検定(情報処理技術者試験, LPIC)</td>
<td align="center">基準が明確</td>
<td align="center">試験のインターバルが長い</td>
</tr>
<tr>
<td align="center">本</td>
<td align="center">情報の精度は高い(はず)</td>
<td align="center">古い, カリキュラムが組みにくい</td>
</tr>
</tbody>
</table></div>
<p>誰でも一つまたは複数の勉強法を試したことがあるはずです. さてこのようにコンテンツは沢山あり勉強するには良い時代・・・となりそうですが(別に否定はしませんが), 個人的な不満があったりします.</p>
<h3 id="本"><a href="#%E6%9C%AC">本</a></h3>
<p>情報が古いとかは承知で買うしそれはそれで勉強になったりするのですが, 復習が困難です. 本によっては課題や復習問題が付いていますが, それを自分で管理するのは面倒です. 特に大量にインプットしたらもう一度同じ本を読むのは億劫です. また全体のカリキュラムも描き難いです. 内容ごとに言語にまたがることも多いので, 効率性も微妙な気はします.</p>
<h3 id="検定"><a href="#%E6%A4%9C%E5%AE%9A">検定</a></h3>
<p>テストは学習において効果が高いとされていますが, 難易度の調整が微妙な気がします. もっと柔軟な習熟度に合わせた学習法が実現できそうです. 他にもテストのインターバルが長すぎる, 学習履歴が残らないと点が不満です.</p>
<h3 id="動画"><a href="#%E5%8B%95%E7%94%BB">動画</a></h3>
<p>動画は見ていると楽しいものもありますが, プログラムの場合追いにくい場合があります. 結局GitHubなどに置かれている完成品を読んだり写経するという羽目になったりします. 復習もやりずらいです.</p>
<h3 id="スクール"><a href="#%E3%82%B9%E3%82%AF%E3%83%BC%E3%83%AB">スクール</a></h3>
<p>金がない(以上)</p>
<h3 id="文書"><a href="#%E6%96%87%E6%9B%B8">文書</a></h3>
<p>ブログのことと思えばいいです. 検索してヒットするとありがたいのですが勉強法としては, 疑問です. 結局ドキュメントのメモだったりするものもあり, ドキュメントを読むということも多々あります. ただエラーへの対処とかは便利だと思います.</p>
<h3 id="アウトプット"><a href="#%E3%82%A2%E3%82%A6%E3%83%88%E3%83%97%E3%83%83%E3%83%88">アウトプット</a></h3>
<p>勉強記録とかGitHubにひたすらコードをあげるという感じです. この開発日記もその一つでしょう. 人に教えるというのは高い学習効果があるとされていますのである程度の効果は見込めそうです. しかし見返す前に同じ内容をググってしまったり, 単なるメモや記事として価値がないようなもの(この記事みたいな?)があったりします. さらに時間がかかります. とはいえ自分の記事に助けられるという機会があった人もいるでしょう.</p>
<h2 id="MinQはどうする?"><a href="#MinQ%E3%81%AF%E3%81%A9%E3%81%86%E3%81%99%E3%82%8B%3F">MinQはどうする?</a></h2>
<p>これらを踏まえてMinQはどうするかです. MinQはクイズベースです. 形式としてはLPICが一番近い気がしますが, 別にプログラミングに限る必要はなく英語や数学なんかもやってみたいです. また学習履歴も細かく管理したいですが, 学習管理サービスは別に作るつもりなのでここでは考えません.</p>
<h3 id="なぜクイズ?"><a href="#%E3%81%AA%E3%81%9C%E3%82%AF%E3%82%A4%E3%82%BA%3F">なぜクイズ?</a></h3>
<p>テスト形式が比較的学習効果が高いそうです(確かそうだったはずです). 作りやすいし, 還元的な手法は物事を理解する基本だと思います. 解析とかもしたいのでデータを細かく取りたいというのもあります. 学習者(現状対象者は私だけですが)は理解していることよりもしていないことを知りたいわけです. また隙間時間で学習できるようにしたいというのもありこの形式を採用しました.</p>
<ul>
<li>学習のリズムを作る</li>
<li>適切な問を適切な時に</li>
</ul>
<h3 id="従来のクイズ・アプリ/サービスとの違いは?"><a href="#%E5%BE%93%E6%9D%A5%E3%81%AE%E3%82%AF%E3%82%A4%E3%82%BA%E3%83%BB%E3%82%A2%E3%83%97%E3%83%AA%2F%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%A8%E3%81%AE%E9%81%95%E3%81%84%E3%81%AF%3F">従来のクイズ・アプリ/サービスとの違いは?</a></h3>
<p>あくまで個人の実験用アプリなのであんまり詳しく考えてませんが, 以下のような感じでしょうか.</p>
<ul>
<li>隙間時間の有効活用</li>
<li>復習のしやすさ</li>
<li>忘却曲線</li>
<li>知識/能力の可視化</li>
</ul>
<p>究極の目標は知識/能力の可視化です. クイズだと単位が小さすぎるのでどうなるか分かりませんが, 知識や技術をネット上で短く切り売りできたら面白いかなと思っています. PRaasS (PRogrammer As a Service)とでも呼んでおきましょうか.</p>
<p>そういう意味ではクイズが目的というよりは能力を可視化するというのが大きな目標になりそうです.</p>
<h2 id="テーブル設計"><a href="#%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E8%A8%AD%E8%A8%88">テーブル設計</a></h2>
<p>でようやく本題ですが, 関係データベースはテーブルから構成されるのですが, テーブルはスキーマと呼ばれる構造を持っています. まずはデータを編集するための管理画面(adminページ)用のテーブルが必要にあります.</p>
<div class="table-responsive"><table>
<thead>
<tr>
<th>カラム名</th>
<th>用途</th>
</tr>
</thead>
<tbody>
<tr>
<td>id</td>
<td>主キー</td>
</tr>
<tr>
<td>user_name</td>
<td>ユーザーの名前</td>
</tr>
<tr>
<td>email</td>
<td>メール・アドレス</td>
</tr>
<tr>
<td>password</td>
<td>暗号化したパスワード</td>
</tr>
</tbody>
</table></div>
<p>こんなところでしょうか. 次はクイズ・テーブルが必要です.</p>
<div class="table-responsive"><table>
<thead>
<tr>
<th align="center">カラム名</th>
<th align="center">用途</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">id</td>
<td align="center">主キー</td>
</tr>
<tr>
<td align="center">question</td>
<td align="center">問題文</td>
</tr>
<tr>
<td align="center">answer</td>
<td align="center">回答/解説</td>
</tr>
<tr>
<td align="center">tag</td>
<td align="center">グループ/カテゴリ名</td>
</tr>
</tbody>
</table></div>
<p>こんなカラムがあれば良いと思うのですが, 問題はanswerカラムとtagカラムです.</p>
<h3 id="問答のフォーマット"><a href="#%E5%95%8F%E7%AD%94%E3%81%AE%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88">問答のフォーマット</a></h3>
<p>いろんな形式がありますが, MinQでは<a target="_blank" rel="nofollow noopener" href="https://nbformat.readthedocs.io/en/latest/">The Jupyter Notebook Format</a>を参考しようと思います. この形式の利点は以下です.</p>
<ul>
<li>複数の形式を簡単に扱える</li>
<li>ビューをシンプルに保てる</li>
</ul>
<p>リスト構造なのでビュー側での表示のロジックが簡単になります. またセルごとに形式を指定するのでパースして内容を解析するという工程が不要です. 例えばMarkdownに数式やコードを埋め込むと, 該当箇所を判別して違うレンダラを利用する必要があります. これをセル単位で管理すると文章か数式かコード片か, あるいは画像かなどは即座に判断できます. 表示もセルのリストなので比較的簡単です.</p>
<h3 id="tagと関連実体"><a href="#tag%E3%81%A8%E9%96%A2%E9%80%A3%E5%AE%9F%E4%BD%93">tagと関連実体</a></h3>
<p>クイズの分類のためにタグをつける場合, クイズが複数の分類に跨ることは普通にありえることです.そのためクイズには複数のタグを持たせられるようにするべきです. 一方でタグからクイズを絞り込むということもできた方が便利でしょう.</p>
<p><a target="_blank" rel="nofollow noopener" href="https://charlesleifer.com/blog/a-tour-of-tagging-schemas-many-to-many-bitmaps-and-more/">A Tour of Tagging Schemas: Many-to-many, Bitmaps and More</a>にはいくつかの方法が解説されていて面白いです.</p>
<p>もっとも素朴な解決策はタグをCSV(Character Seperated Value)形式で保存する方法です. 表示だけのことを考えるとこれで十分ですが, タグをつける理由は表示のためではないでしょう. またビットマップという手法もあります. ビット列をそれぞれのタグの有無と対応づける方法です. n番目のビットが1ならAタグが付いていることと見なすわけです. この方法は検索は効率的ですが, ビット列以上のタグを持てません.</p>
<p><a target="_blank" rel="nofollow noopener" href="https://www.shoeisha.co.jp/book/detail/9784798124704">達人に学ぶDB設計 徹底指南書</a>では学生エンティティと講義エンティティの例が示されています. 両者を繋ぐのが関連実体/関連エンティティの受講です. この受講エンティティと呼ばれるエンティティは学生エンティティと講義エンティティの主キーを組み合わせたキーを主キーします. こうしたテーブル間の関係を多対多の関連 (Many-to-Many relationship)というらしいですが, GORMでは<a target="_blank" rel="nofollow noopener" href="http://gorm.io/docs/many_to_many.html">Joinテーブル</a>という中間テーブルで管理するようです. この機能を使うようにします.</p>
<p>## MariaDB</p>
<p>RDBMS(Relational DataBase Management System)としてはMariaDBを使おうと思います.</p>
<p>### 導入</p>
<p>CentOS 7にはMariaDBが入っていますが, 5.5とバージョンが古いです.</p>
<p>```bash<br />
$ yum list installed | grep mariadb</p>
<p>mariadb.x86_64 1:5.5.64-1.el7 @base<br />
mariadb-libs.x86_64 1:5.5.64-1.el7 @base<br />
mariadb-server.x86_64 1:5.5.64-1.el7 @base<br />
```</p>
<p>これをまずアンインストールします. <a target="_blank" rel="nofollow noopener" href="https://mariadb.com/resources/blog/installing-mariadb-10-on-centos-7-rhel-7/">How to install MariaDB 10 on CentOS 7 / RHEL 7</a>に従って, インストールします. 現状ではバージョン10.4が安定バージョンのようです.</p>
<p><a href="https://crieit.now.sh/upload_images/f9bf88a0a074e399496de2154d0154d25df208e9769e9.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/f9bf88a0a074e399496de2154d0154d25df208e9769e9.png?mw=700" alt="Screenshot 2019-12-12 at 18.30.01.png" /></a></p>
<p><code>bash
sudo systemctl enable mariadb
sudo systemctl start mariadb</code></p>
<p>これでMariaDBが起動しました.</p>
<h3 id="セキュリティ"><a href="#%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3">セキュリティ</a></h3>
<p>次はセキュリティの設定です.</p>
<pre><code class="bash">sudo mysql_secure_installation
</code></pre>
<p>基本的には全てYesでいいらしいです. 途中rootパスワードの設定が必要なのでパスワードを用意しておきましょう.</p>
<pre><code class="bash">mysql -u root -p
</code></pre>
<p>上で設定したパスワードを入力してMariaDBと表示されればオッケーのようです.</p>
<h3 id="文字コードの変更と寿司ビール問題"><a href="#%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E5%A4%89%E6%9B%B4%E3%81%A8%E5%AF%BF%E5%8F%B8%E3%83%93%E3%83%BC%E3%83%AB%E5%95%8F%E9%A1%8C">文字コードの変更と寿司ビール問題</a></h3>
<p>デフォルトの文字コードはutf8とlatin1が混在しているのですが, これをutf8mb4という絵文字も扱える方式に統一するという話です. またutf8mb4にしても照合順序の関係で寿司とビールの絵文字が同値として扱われるという問題があるそうです. ただいずれも絵文字に対応する処理なので現状関係なさそうなのでほっときます.</p>
<p><a target="_blank" rel="nofollow noopener" href="https://onoredekaiketsu.com/mariadb-secure-installation-and-chenge-to-utf8mb4/">MariaDB(MySQL)初期設定時のセキュリティとutf8mb4化の手順</a>を参照するなりググルなりしてください.</p>
<h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2>
<p>次は管理画面とログイン機能を作っていきたいと思います.</p>
<h2 id="Reference"><a href="#Reference">Reference</a></h2>
<p><a target="_blank" rel="nofollow noopener" href="https://linuxize.com/post/install-mariadb-on-centos-7/">Install MariaDB on CentOS 7</a><br />
<a target="_blank" rel="nofollow noopener" href="https://www.digitalocean.com/community/tutorials/how-to-install-mariadb-on-centos-7">How To Install MariaDB on CentOS 7</a></p>
ブレイン
tag:crieit.net,2005:PublicArticle/14923
2019-04-14T15:12:18+09:00
2019-04-22T17:23:17+09:00
https://crieit.net/posts/KUSANAGI-MySQL
KUSANAGI で MySQL が頻繁に落ちる際の対処
<h1 id="環境"><a href="#%E7%92%B0%E5%A2%83">環境</a></h1>
<div class="table-responsive"><table>
<thead>
<tr>
<th>名前</th>
<th>バージョン</th>
</tr>
</thead>
<tbody>
<tr>
<td>VPS</td>
<td>さくらインターネット 4GB</td>
</tr>
<tr>
<td>OS</td>
<td>KUSANAGI 8.4.2-2 (CentOS7 ベース)</td>
</tr>
<tr>
<td>ウェブサーバー</td>
<td>nginx 1.15.10</td>
</tr>
<tr>
<td>PHP</td>
<td>PHP 7.3.4</td>
</tr>
<tr>
<td>MySQL</td>
<td>MariaDB 10.1.38</td>
</tr>
<tr>
<td>アプリケーション</td>
<td>WordPress</td>
</tr>
<tr>
<td>その他</td>
<td><a target="_blank" rel="nofollow noopener" href="https://mackerel.io/">Mackerel</a></td>
</tr>
</tbody>
</table></div>
<h1 id="問題発生"><a href="#%E5%95%8F%E9%A1%8C%E7%99%BA%E7%94%9F">問題発生</a></h1>
<p><a href="https://crieit.now.sh/upload_images/5920b1ba5aa14ecdac4cb2aa0060871a5cb2cb625acd3.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5920b1ba5aa14ecdac4cb2aa0060871a5cb2cb625acd3.png?mw=700" alt="データベース接続確立エラー.png" /></a></p>
<p>サイトにブラウザからアクセスすると「データベース接続確立エラー」となる。</p>
<h1 id="状況確認"><a href="#%E7%8A%B6%E6%B3%81%E7%A2%BA%E8%AA%8D">状況確認</a></h1>
<p>コンソールにて。</p>
<pre><code>sudo cat /var/log/messages
</code></pre>
<p>以下のログを発見。</p>
<pre><code>Apr 14 00:31:06 hoge kernel: mysqld invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0
</code></pre>
<p>MySQL が落ちている。</p>
<h1 id="暫定対処"><a href="#%E6%9A%AB%E5%AE%9A%E5%AF%BE%E5%87%A6">暫定対処</a></h1>
<p>コンソールにて。</p>
<pre><code>sudo systemctl start mysqld
</code></pre>
<p>「データベース接続確立エラー」は解消される。</p>
<h1 id="数時間後に問題再発"><a href="#%E6%95%B0%E6%99%82%E9%96%93%E5%BE%8C%E3%81%AB%E5%95%8F%E9%A1%8C%E5%86%8D%E7%99%BA">数時間後に問題再発</a></h1>
<p><a href="https://crieit.now.sh/upload_images/5920b1ba5aa14ecdac4cb2aa0060871a5cb2cb625acd3.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5920b1ba5aa14ecdac4cb2aa0060871a5cb2cb625acd3.png?mw=700" alt="データベース接続確立エラー.png" /></a></p>
<p>「データベース接続確立エラー」</p>
<h1 id="再度状況確認"><a href="#%E5%86%8D%E5%BA%A6%E7%8A%B6%E6%B3%81%E7%A2%BA%E8%AA%8D">再度状況確認</a></h1>
<p>コンソールにて。</p>
<pre><code>sudo cat /var/log/messages
</code></pre>
<p>同様のログを確認。</p>
<pre><code>Apr 14 07:48:32 hoge kernel: mysqld invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0
</code></pre>
<p><a target="_blank" rel="nofollow noopener" href="https://mackerel.io/">Mackerel</a> でのメモリ状況を確認。</p>
<p><a href="https://crieit.now.sh/upload_images/6f5c7f137838dee61bb62935fd733c5e5cb2c0899c6dd.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/6f5c7f137838dee61bb62935fd733c5e5cb2c0899c6dd.png?mw=700" alt="スクリーンショット 2019-04-14 14.08.10.png" /></a></p>
<p>メモリを食いつぶした後スワップまで喰って無事死亡している。</p>
<h1 id="nginx ログの確認"><a href="#nginx+%E3%83%AD%E3%82%B0%E3%81%AE%E7%A2%BA%E8%AA%8D">nginx ログの確認</a></h1>
<p>詳細は割愛するが、nginx のログを確認したところ、ブルートフォースアタックでの接続数増、pubsubhubbub での接続数増、行儀の悪い bot からの接続数増など様々な痕跡があった。</p>
<p>なお、KUSANAGI による nginx ログは以下の場所に分散している。<br />
(筆者はしばらくの間ログ分散に気付かず、確認に時間がかかった。)</p>
<h2 id="WordPress SSL"><a href="#WordPress+SSL">WordPress SSL</a></h2>
<p>/home/kusanagi/kusanagi_html/log/nginx/ssl_access.log</p>
<p>※ kusanagi_html はプロビジョニングディレクトリ</p>
<h2 id="WordPress HTTP"><a href="#WordPress+HTTP">WordPress HTTP</a></h2>
<p>/home/kusanagi/kusanagi_html/log/nginx/access.log</p>
<p>※ kusanagi_html はプロビジョニングディレクトリ</p>
<h2 id="WordPress 外"><a href="#WordPress+%E5%A4%96">WordPress 外</a></h2>
<p>/var/log/nginx/access.log</p>
<h1 id="恒久対処"><a href="#%E6%81%92%E4%B9%85%E5%AF%BE%E5%87%A6">恒久対処</a></h1>
<p>コンソールにて。</p>
<pre><code>sudo vim /etc/php-fpm.d/www.conf
/pm.max_children =
i
</code></pre>
<p>PHP-FPM の設定を変更する。</p>
<pre><code>pm.max_children = 50
</code></pre>
<p>を以下に変更。</p>
<pre><code>pm.max_children = 17
</code></pre>
<p>[esc] キーで編集終了。</p>
<p>KUSANAGI (nginx + php-fpm) 再起動</p>
<pre><code>sudo kusanagi restart
</code></pre>
<h1 id="対処後の確認"><a href="#%E5%AF%BE%E5%87%A6%E5%BE%8C%E3%81%AE%E7%A2%BA%E8%AA%8D">対処後の確認</a></h1>
<p><a target="_blank" rel="nofollow noopener" href="https://mackerel.io/">Mackerel</a> でのメモリ状況</p>
<p><a href="https://crieit.now.sh/upload_images/69106066dd8c39df5777475fb4ca26045cb2c0a52e60d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/69106066dd8c39df5777475fb4ca26045cb2c0a52e60d.png?mw=700" alt="スクリーンショット 2019-04-14 14.06.51.png" /></a></p>
<p>ピーク時のメモリ消費量が 3.5GB 程度と、上限の 4GB から 0.5GB 程度余裕のある状態で消費しきらずに、スワップアウトも発生しない。</p>
<p>結果、「データベース接続確立エラー」とならず接続状況は安定している。</p>
<h1 id="解説"><a href="#%E8%A7%A3%E8%AA%AC">解説</a></h1>
<p>PHP-FPM の <code>pm.max_children</code> はアプリケーションの最大プロセス数。php.ini ファイルでの <code>memory_limit</code>は <code>128M</code> に設定されているため、<code>pm.max_children</code> を <code>17</code> に設定した場合 PHP-FPM のみで食いつぶすメモリ量を 2GB 程度に抑えることができる。<br />
デフォルトで 1GB 程度消費しているため、計約3GB。さらに MySQL などで 0.5GB 程度消費しているものと思われる。<br />
詳細は <code>top</code> コマンド等で確認できる。</p>
<h1 id="今後"><a href="#%E4%BB%8A%E5%BE%8C">今後</a></h1>
<p>万が一落ちた場合に monit で MySQL の自動再起動、fail2ban によるブロッキング設定を行いたいが後ほど。</p>
<h1 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h1>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/AknEp/items/42421a4c3a4a3a8d8991">php-fpmとRAMのお勉強メモ。KUSANAGIで試した。 - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://gist.github.com/kitak/6349463">コマンドによる「負荷」の原因切り分け</a></li>
</ul>
sola
tag:crieit.net,2005:PublicArticle/14902
2019-04-04T03:18:36+09:00
2019-05-09T21:31:39+09:00
https://crieit.net/posts/MariaDB-InnoDB
MariaDB の InnoDB がぶっ壊れて起動できなくなったので復旧した
<h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1>
<p>右往左往して復旧に6時間程度かかった。もうこりごりなので内容をざっくりまとめる。</p>
<h1 id="手順(概略)"><a href="#%E6%89%8B%E9%A0%86%EF%BC%88%E6%A6%82%E7%95%A5%EF%BC%89">手順(概略)</a></h1>
<p>KUSANAGI(CentOS7)での手順。</p>
<pre><code>sudo su
vi /etc/my.cnf.d/server.cnf
i
</code></pre>
<pre><code>[mysqld]
innodb_force_recovery = 3
</code></pre>
<p>[esc] キーで vi 終了。</p>
<pre><code>systemctl start mysqld
mysqldump -u root -p -x --all-databases > alldatabase.dump
systemctl stop mysqld
rm -rf /var/lib/mysql/*
yum remove -y MariaDB-devel MariaDB-client MariaDB-server
yum install -y MariaDB-devel MariaDB-client MariaDB-server
systemctl start mysqld
mysql -u root
UPDATE mysql.user SET password=password('password') WHERE user = 'root';
CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';
GRANT ALL ON db_name.* TO 'username'@'localhost';
flush privileges;
exit;
mysql -u root -p < alldatabase.dump
</code></pre>
<h1 id="要点"><a href="#%E8%A6%81%E7%82%B9">要点</a></h1>
<ul>
<li><code>innodb_force_recovery</code> を 3 以下に設定しておくと InnoDB が壊れていても Read only でとりあえず起動出来るようになるっぽい</li>
<li>起動したら mysqldump でバックアップ。MariaDB を再インストール後に戻す</li>
<li>構成ファイルがいかれていたので <code>/var/lib/mysql/</code> 配下を消しておく。(必要であれば設定ファイルは逃しておく)</li>
</ul>
<h1 id="原因"><a href="#%E5%8E%9F%E5%9B%A0">原因</a></h1>
<p>数日前に単純に MariaDB が落ちたことがあり、何かしら高負荷がかかっている可能性があるが、アクセス数も多くなく、環境である仮想ハードウェアの負荷も目立った様子は無い。できれば関係ログを追って探りたいところだが不明。</p>
<h2 id="(2019.4.14 追記) 原因判明したので記事書きました"><a href="#%282019.4.14+%E8%BF%BD%E8%A8%98%29+%E5%8E%9F%E5%9B%A0%E5%88%A4%E6%98%8E%E3%81%97%E3%81%9F%E3%81%AE%E3%81%A7%E8%A8%98%E4%BA%8B%E6%9B%B8%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F">(2019.4.14 追記) 原因判明したので記事書きました</a></h2>
<p><a href="https://crieit.net/posts/KUSANAGI-MySQL">KUSANAGI で MySQL が頻繁に落ちる際の対処 - Crieit</a></p>
<h1 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h1>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/skouno25/items/71174c959abe435223ab">MySQLでInnoDB破損したときの復旧方法 - Qiita</a></li>
</ul>
sola