そうなったときに備えて覚え書き。
月: 2016年4月
[MySQL] 壊れたテーブルを修復する
前のエントリで書いた通り、突然サーバーが高負荷になって何も受け付けなくなったので、仕方なくシャットダウン。再起動後にログを見回ったら、MySQL (実体はMariaDB) のログにエラーが記録されていた。やばい予感。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
mysqld_safe Number of processes running now: 0 mysqld_safe mysqld restarted mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql [Note] /usr/libexec/mysqld (mysqld 5.5.44-MariaDB) starting as process 1532 ... InnoDB: The InnoDB memory heap is disabled InnoDB: Mutexes and rw_locks use GCC atomic builtins InnoDB: Compressed tables use zlib 1.2.7 InnoDB: Using Linux native AIO InnoDB: Initializing buffer pool, size = 128.0M InnoDB: Completed initialization of buffer pool InnoDB: highest supported file format is Barracuda. InnoDB: The log sequence number in ibdata files does not match InnoDB: the log sequence number in the ib_logfiles! InnoDB: Database was not shut down normally! InnoDB: Starting crash recovery. InnoDB: Reading tablespace information from the .ibd files... InnoDB: Restoring possible half-written data pages from the doublewrite InnoDB: buffer... InnoDB: Waiting for the background threads to start Percona XtraDB (http://www.percona.com) 5.5.43-MariaDB-37.2 started; log sequence number 13888240 [Note] Plugin 'FEEDBACK' is disabled. [Note] Server socket created on IP: '0.0.0.0'. [ERROR] mysqld: Table './mysql/user' is marked as crashed and should be repaired [Warning] Checking table: './mysql/user' [ERROR] mysql.user: 1 client is using or hasn't closed the table properly [ERROR] mysqld: Table './mysql/db' is marked as crashed and should be repaired [Warning] Checking table: './mysql/db' [ERROR] mysql.db: 1 client is using or hasn't closed the table properly [Note] Event Scheduler: Loaded 0 events [Note] /usr/libexec/mysqld: ready for connections. Version: '5.5.44-MariaDB' socket: '/var/lib/mysql/mysql.sock' port: 3306 MariaDB Server [ERROR] mysqld: Table './db1/wp_options' is marked as crashed and should be repaired [Warning] Checking table: './db1/wp_options' [ERROR] mysqld: Table './db1/wp_posts' is marked as crashed and should be repaired [Warning] Checking table: './db1/wp_posts' [ERROR] mysqld: Table './db1/wp_comments' is marked as crashed and should be repaired |
WordPressは問題なく動作しているように見えるけど、念のためリカバリしておいたほうがいいだろう。ということで、エラーチェックとリカバリ用のコマンド (SQL) を覚え書き。
1 2 |
check table <table_name>; repair table <table_name>; |
これらコマンドを実行してみたけど何も起きなかった。起動時に走ったリカバリ処理が問題を解決してくれた模様。大事にならなくて良かったねー
参考サイト
MySQL の壊れたテーブルを修復
http://macperson.net/mysql-table-repair/
[Webサイト運営] 突然サーバー負荷上昇。DDoSか?
ある晩、監視サービスからアラートメールが飛んできた。このウェブサーバーがダウンした模様。原因は読み込みタイムアウトだって。500とかじゃなくてタイムアウト?早速調べるためにssh接続を試みるもログインプロンプトさえ表示されない。やばい予感、マジで焦る。
DigitalOceanのコントロールパネルからサーバーのロード状態を見ると、CPU負荷が140%、ディスクアクセスが2MB/sを超えている。普段はCPU負荷は10%を超えることは稀で、ディスクアクセスも常時ゼロに等しい。明らかに何かが起きているな。コントロールパネルからコンソール接続を試みるも反応無し。もう打つ手無しと諦めてDropletを電源オフする。少し待って再投入したところ、元の静かな状態に戻った。
以下がロード状態のグラフ。8:00pmごろから負荷が急激に上がっている。再起動したことで元の状態に戻ったので、高負荷状態は20分以内で収まった。もし外出先とかですぐ対応できなかったらと思うと恐ろしい。
原因は何だったのだろうか。最初に疑ったのはDDoS。Apacheのログを見たんだけど、疑わしいアクセスは十数件程度しか記録されていない。それは異なるGeoロケーションからのアクセスだけどAgentはどれも同じ名前のロボット。各地のマシンを踏み台にして集中アクセスしてきたのだろうか。だとしたらログ件数が少なすぎる。こんな弱小サイトが、ウェブサーバーでログが記録できなくなるほどの集中砲火を浴びるとは考え難いよなぁ。
他の可能性としては、サーバー上で稼動するソフトの暴走とか?。でも、サーバー上のログを一通り目を通してみたけど、怪しい挙動を示すものは見つからず。もう何ヶ月も同じコンフィギュレーションで稼動させているけど、こんなことが起こったのは初めて。原因がわからないのは気持ち悪いけど、いろいろ考えて出来る限りの方策はしておかないとなーと実感した出来事だった。
[Elasticsearch] LogstashでNginxアクセスログをバッチで読み込む
今回読み込もうとするNginxのアクセスログは以下の形式。
1 2 3 4 5 |
xxx.xxx.xxx.xxx - - [24/Feb/2016:22:46:17 -0800] "GET /images/sample.jpg HTTP/1.1" 200 29160 "http://www.example.com/index.php" "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-CN; GT-I9205 Build/JDQ39) AppleWebKit/ 534.30 (KHTML, like Gecko) Version/4.0 UCBrowser/10.9.4.728 U3/0.8.0 Mobile Safa ri/534.30" |
設定ファイル
ngnix-import.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
input { stdin { } } filter { grok { match => [ "message" , "%{COMBINEDAPACHELOG}+%{GREEDYDATA:extra_fields}"] overwrite => [ "message" ] } mutate { convert => ["response", "integer"] convert => ["bytes", "integer"] convert => ["responsetime", "float"] } geoip { source => "clientip" target => "geoip" add_tag => [ "nginx-geoip" ] } date { match => [ "timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ] remove_field => [ "timestamp" ] } useragent { source => "agent" } } output { # stdout { codec => rubydebug } elasticsearch { hosts => '127.0.0.1:9200' } } |
1 2 |
$ /opt/logstash/bin/logstash -f nginx-import.conf --configtest Configuration OK |
アクセスログの読み込み
1 |
$ /opt/logstash/bin/logstash -f nginx-import.conf < access.log |
実際に試してみたら、大きなアクセスログファイルではLogstashが途中終了してしまった。5万行ずつ分割したら、それぞれ最後まで正常に読み込めた。分割すればいいのならそうしようと調べず仕舞いだけど、もしかすると何か設定があるのかもしれない。
参考サイト
NGINX Log Analysis with Elasticsearch, Logstash, and Kibana
http://logz.io/blog/nginx-log-analysis/
Setting up Logstash 1.4.2 to forward Nginx logs to Elasticsearch | Bravo Kernel
http://www.bravo-kernel.com/2014/12/setting-up-logstash-1-4-2-to-forward-nginx-logs-to-elasticsearch/
[Elasticsearch] 予備知識 – shardとreplica
Headプラグインでは数字の四角が画面に表示される。それらはshardとかreplicaを示してるらしい。何だそれ?
以下、予備知識として参考サイト。
Elasticsearchのshardとreplica – なんかかきたい
http://t-cyrill.hatenablog.jp/entry/2015/02/18/190310
elasticsearch シャードとか、インデックスとか – notebook
http://swfz.hatenablog.com/entry/2015/07/22/040354
Elasticsearch システム概要 — Hello! Elasticsearch. — Medium
https://medium.com/hello-elasticsearch/elasticsearch-afd52d72711#.mnapv5rm3
[Laravel] タスクスケジューリングを使って処理を自動実行する
ざっと実装手順を覚え書き。
コマンドの実装
1 2 |
$ php artisan make:console DailyUpdate --command="dailyupdate" Console command created successfully. |
app\Console\Commands\DailyUpdate.php
1 2 3 4 5 6 7 8 9 10 11 12 |
class DailyUpdate extends Command { /** * Execute the console command. * * @return mixed */ public function handle() { echo 'hello'; } } |
app\Console\Kernel.php
1 2 3 4 5 6 7 8 9 10 11 12 |
class Kernel extends ConsoleKernel { /** * The Artisan commands provided by your application. * * @var array */ protected $commands = [ // Commands\Inspire::class, Commands\DailyUpdate::class, ]; } |
テスト
1 2 |
$ php artisan dailyupdate hello |
スケジューリング
app\Console\Kernel.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class Kernel extends ConsoleKernel { /** * Define the application's command schedule. * * @param \Illuminate\Console\Scheduling\Schedule $schedule * @return void */ protected function schedule(Schedule $schedule) { // $schedule->command('inspire') // ->hourly(); $schedule->command('dailyupdate')->dailyAt('00:05'); } } |
あとはcronを設定する。
参考サイト
Task Scheduling – Laravel – The PHP Framework For Web Artisans
https://laravel.com/docs/master/scheduling
Laravel5でバッチ開発 | プログラミングメカブログ
http://blog.mekachan.net/?p=198
laravelでバッチ作ってcronで動かしてみた – Qiita
http://qiita.com/ritukiii/items/a70d89fa988b2d9afbc4
[WordPress] 問い合わせフォームプラグイン
以下の2つが定番っぽいのでメモ。共に開発は日本人の模様。
Contact Form 7
Contact Form 7
http://contactform7.com/ja/
Contact Form 7プラグイン(問い合わせメールフォームを作成) – WordPressプラグインの一覧
http://www.adminweb.jp/wordpress-plugin/list/index10.html
NW WP Form
Contact Form 7に無い機能として以下がある。
- 「お問い合わせ画面」「確認画面」「送信完了画面」「エラー画面」を作ることが出来る
- メールのデータをデータベース内に保存出来る (保存機能はオフにできる)
問い合わせデータをデータベースに保存することでCRMのようにも使えそう。
MW WP Form
http://plugins.2inc.org/mw-wp-form/
Contact Form7よりも使いやすいお問い合わせフォーム用WordPressプラグインMW WP Formの紹介 | mono-lab
http://www.mono-lab.net/147/
受託案件で活躍しそうなWordPressメールフォームプラグイン「MW WP Form」を使ってみた – マイペースクリエイターの覚え書き
http://mypacecreator.net/blog/archives/2063
[Unix] time – コマンドの実行時間を測定する
以下のように先頭にtimeを付けて実行すれば実行すればよし。
1 |
$ time <コマンド> |
参考サイト
Linuxコマンド集 – 【 time 】 指定したコマンドの実行時間を表示する:ITpro
http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230902/
[PHP] クロージャーが親のスコープから変数を引き継ぐ方法
use を使えば引き継げる。覚え書きとして、以下マニュアルからサンプルを抜粋。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<?php $message = 'hello'; // "use" がない場合 $example = function () { var_dump($message); }; $example(); // $message を引き継ぎます $example = function () use ($message) { var_dump($message); }; $example(); // 引き継がれた変数の値は、関数が定義された時点のものであり、 // 関数が呼ばれた時点のものではありません $message = 'world'; $example(); // $message をリセットします $message = 'hello'; // 参照渡しで引き継ぎます $example = function () use (&$message) { var_dump($message); }; $example(); // 親のスコープで変更された値が、 // 関数呼び出しの内部にも反映されます $message = 'world'; $example(); // クロージャは、通常の引数も受け付けます $example = function ($arg) use ($message) { var_dump($arg . ' ' . $message); }; $example("hello"); ?> |
参考サイト
PHP: 無名関数 – Manual
http://php.net/manual/ja/functions.anonymous.php
PHPでクロージャーを使う – Qiita
http://qiita.com/hugo-sb/items/3e344486658e3cfbd407
[JavaScript] クリックしても何も起きないダミーのアンカー(リンク)
デザイナーから上がってきたHTMLファイルに、ページ遷移を必要としないんだけどアンカーが使われている箇所が幾つかあった。
1 2 3 |
<span class="foo"> <a href="#">Hello</a> </span> |
スタイルシートで “foo a” の見栄えが設定されているけど、アンカーは生きているのでクリックするとページがリロードされてしまう。クリッカブルな挙動はjQueryで制御するとして、HTMLのアンカーとしての機能は殺しておきたい。どうするか。
手っ取り早いのは以下かな。
1 2 3 |
<span class="foo"> <a href="javascript:void(0);">Hello</a> </span> |
参考サイト
クリックしても何も起こらないダミーのa要素 – Qiita
http://qiita.com/448jp/items/dbd2e4ee0a6ec500d329