ちょっと厨二っぽいSEのブログ

プログラミングとかのシステム備忘録など

【mysql】CodeIgniterのDB設定の罠【Sleep】

前回の記事ryokwkm2.hatenadiary.jp


この時なにが起こっていたのかを書きます

Sleepしてるクエリが多いから消してやればいいやーAHAHAHAとはさすがになりません
これが起きた原因を排除します

結論からいいますと、phpフレームワーク codeIgniter のDB設定に問題がありました


正しい設定は以下の通り

$db['default']['hostname'] = 'XXX.XXX.XXX.XXX';
$db['default']['username'] = 'ユーザー名';
$db['default']['password'] = 'パスワード';
$db['default']['database'] = 'DB名';

$db['default']['dbdriver'] = 'mysql';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = FALSE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = FALSE;
$db['default']['stricton'] = FALSE;


問題の設定はここです

$db['default']['pconnect'] = FALSE;
$db['default']['autoinit'] = FALSE;

pconnectがONになっていると、一度接続したコネクションは破棄されず、保持して使いまわします
phpからmysqlに再アクセスする際、高速にアクセスできるのですが
DB側のコネクション数が最大になってしまい、DBにアクセスできなくなっていたというわけです

autoinitは、ライブラリがロードされたときに、データベースに自動的に接続するかどうか。もし FALSE に設定された場合、最初のクエリの実行の前に接続されます

ちなみに、CodeIgniterの初期設定ではこれらがONになっています
かならずOFFにするようにしましょう

【mysql】プロセスを条件検索で取得する方法【sleep】

DB負荷が高くなると、処理に長時間かかっているクエリが複数出てきてフリーズに近い状態になります。
以前以下の記事のような事象がおき、特定クエリの大量kill が必要になりました。
ryokwkm2.hatenadiary.jp


実行中のプロセスは以下のコマンドを使用して調べることができます

mysql> show processlist;

もしくはmysqlにログインせずに以下のコマンドでも可能です。
mysqladmin processlist

使用例(パスワードが設定されている場合)
mysqladmin processlist -u ユーザー名 -p

実行してみると以下のように結果が表示されました。

+----------+-------+-----------------------+-------------------+-------------+----------+-----------------------------------------------------------------------+------------------+
| Id       | User  | Host                  | db                | Command     | Time     | state                                                                 | info             |
+----------+-------+-----------------------+-------------------+-------------+----------+-----------------------------------------------------------------------+------------------+
| 1        | repl  | 192.168.0.142:47616   |                   | Binlog Dump | 18174357 | Master has sent all binlog to slave; waiting for binlog to be updated |                  |
| 43401230 | mysql | 183.79.135.206:43180  | DB名              | sleep       | 190      |                                                                       |                  |
| 43401247 | mysql | 183.79.135.206:43200  | DB名              | sleep       | 40       |                                                                       |                  |
| 43401313 | mysql | 183.79.135.206:43267  | DB名              | sleep       | 45       |                                                                       |                  |
| 43401694 | mysql | 183.79.135.206:43781  | DB名              | sleep       | 71       |                                                                       |                  |
| 43401820 | mysql | 183.79.135.206:43972  | DB名              | sleep       | 153      |                                                                       |                  |
| 43401853 | mysql | 183.79.135.206:44018  | DB名              | sleep       | 649      |                                                                       |                  |
| 43401945 | mysql | 183.79.135.206:44121  | DB名              | sleep       | 732      |                                                                       |                  |
| 43401958 | mysql | 183.79.135.206:44141  | DB名              | sleep       | 43       |                                                                       |                  |
| 43757186 | mysql | 183.79.135.206:55732  | DB名              | sleep       | 944      |                                                                       |                  |
| 43757260 | mysql | 183.79.135.206:55786  | DB名              | sleep       | 42       |                                                                       |                  |
| 43757279 | mysql | 183.79.135.206:55823  | DB名              | sleep       | 20       |                                                                       |                  |
| 43757284 | mysql | 183.79.135.206:55827  | DB名              | sleep       | 86       |                                                                       |                  |
| 43757302 | mysql | 183.79.135.206:55842  | DB名              | sleep       | 39       |                                                                       |                  |
| 43757306 | mysql | 183.79.135.206:55847  | DB名              | sleep       | 129      |                                                                       |                  |
| 43757307 | mysql | 183.79.135.206:55848  | DB名              | sleep       | 47       |                                                                       |                  |
| 43757353 | mysql | 183.79.135.206:55884  | DB名              | sleep       | 45       |                                                                       |                  |
| 43757356 | mysql | 183.79.135.206:55886  | DB名              | sleep       | 45       |                                                                       |                  |
| 43757374 | mysql | 183.79.135.206:55894  | DB名              | sleep       | 43       |                                                                       |                  |
| 43757385 | mysql | 183.79.135.206:55904  | DB名              | sleep       | 275      |                                                                       |                  |
| 43765522 | mysql | 183.79.135.206:35928  | DB名              | sleep       | 620      |                                                                       |                  |
| 43765933 | mysql | 183.79.135.206:36545  | DB名              | sleep       | 82       |                                                                       |                  |

(略)

+----------+-------+-----------------------+------------------+-------------+----------+------------------------------------------------------------------------+------------------+

GYAAAAAAAAAAAAAAAAAAA!

上記事でも書いていますが、特定のスキーマに対して長時間sleepしているプロセスのみkill する必要があります。

プロセスは以下のようなコマンドでkillできます。

mysql> kill プロセス番号

もしくはmysqlにログインせず
mysqladmin kill プロセス番号 -h localhost -u ユーザー名 -p

ただし、これら大量のプロセスを一個一個消していくのは骨が折れます。
そこで、条件を指定して一気に削除する方法を試しましょう

プロセスリストはSQLでも可取得能です。

SQLで条件を指定してプロセスIDを取得しましょう。
その後killコマンドで一気に削除します
mysqladmin killでは複数のIDを指定できますので1コマンドで完了します


information_schema.processlist に対して実行します。

use information_schema;
SELECT * FROM PROCESSLIST WHERE TIME > 59;

プロセス番号だけ取得するには以下のように指定します

SELECT GROUP_CONCAT(ID) FROM PROCESSLIST WHERE TIME > 59;


あとお好きな条件を指定しましょう
DBを限定するには以下のようにします

SELECT GROUP_CONCAT(ID) FROM PROCESSLIST WHERE TIME > 59 AND DB = "DB名";

ここで取得できたIDをコピーして、以下のようにプロセスを削除すれば完了です

mysqladmin kill 43401230,43401247,43401313,43401694,43401820,43401853,43401945,43401958,43757186,43757260.... -h localhost -u ユーザー名 -p

【Android】画像データをこねくり回す

画像データをこねくり回します

  • ImageViewに画像を設定
  • リソースIDから画像のBitmapを取得
  • BitmapをImageViewに表示させる
  • Bitmapをbyte配列に変換する
  • byte配列をBitmapに変換する
  • byte配列をBase64(String)に変換する
  • Base64データを、webViewのimgタグに画像として表示させる


今回やりたかったのは、
- サーバーから画像データを取得 > それをWeView上で広告として表示

なのですが、
ついでに画像データの扱いについてまとめました



ImageViewに画像を設定

まずは一番簡単な方法
LayoutのXMLに直接書きます
HTMLのimgタグのような感じです

<ImageView
   android:id="@+id/image01"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:src="@drawable/ic_launcher" />


次にコードから設定します

ImageView imageView = (ImageView)findViewById(R.id.image01);
imageView.setImageResource(R.drawable.ic_launcher);

リソースIDから画像のBitmapを取得

リソースIDから画像データを取得したい場合は以下のように記述します

Resources r = getResources();
Bitmap bmp = BitmapFactory.decodeResource(r, R.drawable.ic_launcher);

BitmapをImageViewに表示させる

ImageView imageView = (ImageView)findViewById(R.id.image01);
imageView.setImageBitmap(bmp); 

上記のコードは一応書きましたが、私はあまり書きません
普段はAndroiodQueryというライブラリを使用していて、それを使用して設定しています
AndroidQueryを使えば、Jqueryを書くように簡単に画像の設定が出来ます
詳しくは今度まとめようと思います



Bitmapをbyte配列に変換する

取得したBitmapデータをbyte配列に変換する方法です

compressメソッドの第2引数はcompressorへのヒント用に0-100の値を入れ、0は画像サイズが小さいことを示し、100は大きいことを示します。
通常は100でOKでしょう
第1引数は画像の形式です

ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] bytes = stream.toByteArray();

byte配列をBase64(String)に変換する

base64は、WebView内に動的に画像の設定を行うときなどに使用します
わけあってImageURLを直接指定できない時などは最適です(例えば取得元のサーバーにBasic認証がかかっている場合など)
一定間隔で改行が入ってしまうのでそれを取り除くことを忘れないようにしましょう
encodeToStringの第2引数にBase64.NO_WRAPを指定すると改行は消せます

String strBase64 =  Base64.encodeToString(bytes, Base64.NO_WRAP);

Base64データを、webViewのimgタグに画像データを表示させる

今回やりたかったのはこれです
webViewに対してjavascriptを実行して設定します

ただし、画像データをサーバーから取得する場合など
WebViewをレンダリングするタイミングがずれる場合は別の方法も考える必要があります

お手軽にJqueryでやります

  • html
<div id="webad01" style=" display:none;"><img src="" ></div>
function viewImage(tagId, imageUrl) {
	
	$("#"+tagId+" img").attr("src", imageUrl );
	$("#"+tagId).show();
}
  • java
    • javascript側の関数を実行します
    • ポイントは、base64データの頭に"data:image/png" などの画像形式が必要なところです
//strBase64 にBase64データが入っています
String imageID = "webad01";	//Imgタグに設置するID
String base64ImgHtml = "data:" + "image/png" + ";base64," + strBase64;
String js = String.format("viewImage(\"%s\", \"%s\");", imageID, base64ImgHtml);
webview.loadUrl( "javascript:" + js );

【Windows】gitは正常に終了しませんでした (終了コード 128)【解決方法】

TortoiseGitを使用していて以下のエラーになる場合


gitは正常に終了しませんでした (終了コード 128)


ネットを漁ると、SSHをGitのものにしろとか出ます

フォルダに作成されるエラーログ(sh.exe.stackdump)
を見てみると、こんな感じのエラーが出ていました

                          • -

11974 [main] sh 23816 handle_exceptions: Exception: STATUS_ACCESS_VIOLATION
13284 [main] sh 23816 handle_exceptions: Error while dumping state (probably corrupted stack)

                          • -

Process Monitor で見てみると、sh.exe が起動する時に %TEMP% に対して QueryDirectory を実行して、ファイルの一覧を拾った直後で落ちている様子。
どうもこのフォルダに日本語を含むファイルが存在しているとエラーになるようです

%TEMP%は環境変数です
こんな感じのフォルダパスが格納されています
- C:\Users\XXXXX\AppData\Local\Temp

フォルダに直接 %TEMP% とすればアクセスできますので、それでアクセスしてみます


このフォルダ内にある日本語のファイル名のファイルを削除します
ファイル名で並び替えすると簡単に見つけられます

するとさくっと動作しました

この問題はGit以外でも度々起こるようです

【Windows】Xcodeのキー入力をWindows風にする方法【Mac】

Windowsユーザーで、iosアプリのために仕方なくXcodeを使用しているみなさん
入力しづらくありませんか?

例えば一行全てを選択する時、
Windowsでは
shift + fn + →(shift + end)なんですが、Xcodeの場合は(shift + ctrl + → ) です

私は普段、Eclipse, Dreamweaver, 秀丸あたりをエディタとして使用してるんですが、入力方法はどれも同じです
Xcodeを使うと入力方式が違いすぎてストレスがたまります
MacWindowsで入力方式が違うのかな)


ということで、Xcodeの入力方式をWindowsに合わせましょう

◇Step.1
まず最初に、mac bookをお使いの方、
Windowsでは本来Ctrlキーがある場所にcapsキーがありますよね
これが邪魔なので、capsキーにcontrolキーを割り当てて下さい
やり方は省略しますが、Macの設定画面から簡単に行うことが出来ます


◇Step.2
次にXcodeの設定です

キーバインドの設定を修正します
キーバインドとは、ショートカットのことです。
普段私達は「Shift + 矢印」 で単語を選択していますが、これもショートカットに含まれますので、
ここを修正すると、キーの入力方式をWindows風にすることが出来るというわけです

○設定ウィンドウを開く

Xcode > Preferrence > Key Bindings

この画面で修正できます、

ですが、元に戻せるようにキーバインドの設定を新しく作成し、それを編集しましょう

○新しくキーバインドセットを作成する

・Key Bindings Setのセレクトボックスから、Manage Key Bindings... を選択

・左下の+ボタンを押すと作成できます。名前はお好きなものを付けてください

新しく作成できたら、設定を以下のように修正すれば完了です


○設定内容
Move Subword Forward >Ctrl + →  (単語ごとに移動します)
Move Subword Forward Extending Selection >Ctrl + shift + →
Move Subword Backward >Ctrl + ←
Move Subword Backward Extending Selection >Ctrl + shift + ←

Move Word Right >Alt + →  (これは move subword forward より少し大きく移動する)
Move Word Left >Alt + ←

Move to Right End of Line >Fn + →
Move to Left End of Line >Fn + ←
Move to Right End of Line Extending Selection >Fn + shift + →
Move to Left End of Line Extending Selection >Fn + shift + ←


以下は上の変更で競合するものを変更しました
Move to Beginningg of Document Extending Selection >Ctrl + shift + Fn + ↑ (適当に)
Move to End of Document Extending Selection >Ctrl + shift + Fn + ↓ (適当に)
Scroll to Beginning of Document >削除
Scroll to End of Document >削除


一応最低限のものだけ設定しました

みなさま、ごきげんなXcodeライフを!

【c++】ひらがなをカタカナへ変換する

c++で、ひらがなをカタカナへ変換するライブラリを作りました

C++文字コード変換をするにはlibiconvまたはicuというライブラリを用いるのが一般的なようです
ただしこれらは難易度が高くて手軽に扱えません

phpでは1行で済むのでc++でもサクッといくかと思ったのになぁ)

C++ライトユーザーの皆様はこちらのコードをご使用下さい

ひらがなをカタカナへ変換する