Amazon RDS for MySQL で Too many connections
長時間実行してるバッチアプリケーションで、RDSのMySQLが
「Too many connections」て言うようになって困っていました。
MySQLの同時接続数 max_connections の設定値が足りないのかなと
思いきや、information_schema.PROCESSLIST の中身を見たら
mysql> SELECT * FROM information_schema.PROCESSLIST WHERE USER='user' and Command='Sleep' and TIME > 1000\G *************************** 1. row *************************** ID: 66825542 USER: user HOST: ip-01-23-45-67.ap-northeast-1.compute.internal:xxxxx DB: db COMMAND: Sleep TIME: 4306 STATE: INFO: NULL *************************** 2. row *************************** ID: 66825357 HOST: ip-01-23-45-67.ap-northeast-1.compute.internal:xxxxx DB: db COMMAND: Sleep TIME: 4325 STATE: INFO: NULL (省略) 213 rows in set (0.00 sec)
大漁!大漁にある!
バッチの中で接続の切断/破棄が正しくできていないようです。
正しく切断/破棄できるよう、根本の調査が必要なのですが
取り急ぎ、長々と眠っているプロセスをkillします。
mysql> kill 66825542; ERROR 1095 (HY000): You are not owner of thread 66825542
oh,
門前払いをくらいました。
killコマンド、スーパーユーザーしか実行できないようです。
調べたところ、RDSでは mysql.rds_kill および mysql.rds_kill_query
という、killコマンドの代わりになるものが提供されてました。
早速実行してみます。
mysql> CALL mysql.rds_kill(66825542); Query OK, 0 rows affected (0.00 sec)
おお!
無事消えました!
詳しくはこちらをどうぞ
kill mysql thread
https://forums.aws.amazon.com/message.jspa?messageID=337243
10.8 Mountain Lion から 10.9 Mavericksへアップグレードしたらapacheのphpサイトが死んだ
バーチャルホストで用意してある複数のサイトのうち、htmlのサイトは平気なのに
phpのサイトだけ
[notice] child pid XXX exit signal Segmentation fault (11)
これがでる。
クラッシュレポートを見てみると、libphp5.soの読み込みの途中で息絶えてた。
アップグレードで再インストールされたApacheとPHPのバージョンが合ってない?
と思いphpのバージョンを5.5へあげてみる。
curl -s http://php-osx.liip.ch/install.sh | bash -s 5.5
んで、LoadModule php5_moduleを以下に変えてみた。
/usr/local/php5-5.5.XXXX/libphp5.so
結果、動作するようになった!と思いきや、アプリケーション内で使用してる
aws-sdkのSimpleDBのとこで
Maximum function nesting level of XXX reached, aborting!
を返す。
Fixed circular to string method in simplexml #39
https://github.com/amazonwebservices/aws-sdk-for-php/pull/39
PHP 5.3.10では出ないけど、PHP 5.4.7で発生するエラーらしい。
Fixed案件なのでSDKのバージョンを上げれば解決なんですが、ここはPHPの
バージョンを5.3に落とすことにした。
curl -s http://php-osx.liip.ch/install.sh | bash -s 5.3
そしてlibphp5.soを5.3に差し替え。ようやく動作するようになりました。
ここまでありつくのに、gdbで動作させたり、その準備でXcodeのコマンド
ラインツールいれたりと無駄にすごい時間を費やしてしまった。
MySQLでDELETE IF EXISTSでおこられた
おこなの?
PRIMARY KEY (`key`,`value`)
のテーブル
key | value |
---|---|
1 | hoge |
1 | fuga |
2 | hoge |
3 | fuga |
4 | hogefuga |
で、値が「hoge」「fuga」のデータの値を「hogefuga」に統一したい。
key | value |
---|---|
1 | hogefuga |
2 | hogefuga |
3 | hogefuga |
4 | hogefuga |
って形にしたいとき、
--「hoge」を「hogefuga」に更新 update テーブル set value = "hogefuga" where value = "hoge"; --「fuga」かつ同じkeyで「hogefuga」持ってるデータを削除 delete from テーブル where value = "fuga" and exists( select t2.* from テーブル t2 where t2.value = "hogefuga" and t2.key = t1.key ); -- >>> おこられるorz
なもんでこうして対応
--「hoge」を「hogefuga」に更新 update テーブル set value = "hogefuga" where value = "hoge"; --「fuga」かつ同じkeyで「hogefuga」持ってるデータを「deleted」に更新 update テーブル t1 inner join ( select key from テーブル where value = "hogefuga" ) t2 on t1.key = t2.key set value = "deleted" where value = "fuga"; --「deleted」データを削除 delete from テーブル where value = "deleted";
なんか回りくどい
Apache CXF:RequestHandler.handleRequestのMessageの値
すぐ忘れるのでメモ
for (Entry<String, Object> m : message.entrySet()) { System.out.println(m.getKey()+":"); System.out.println(" "+String.valueOf(m.getValue())); }
した結果が↓
org.apache.cxf.message.Message.PROTOCOL_HEADERS: {Accept=[*/*], accept-encoding=[gzip,deflate,sdch], accept-language=[ja,en-US;q=0.8,en;q=0.6], cache-control=[no-cache], connection=[keep-alive], Content-Length=[999], content-type=[multipart/form-data; host=[example.com], user-agent=[Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML,like Gecko) Chrome/26.0.1410.64 Safari/537.31]} path_to_match_slash: /v1/service/method HTTP_CONTEXT_MATCH_STRATEGY: stem http.service.redirection: null org.apache.cxf.request.url: http://example.com/example-services/v1/service/method org.apache.cxf.request.uri: /example-service/v1/service/method org.apache.cxf.resource.method: public javax.ws.rs.core.Response com.example.api.service.v1.impl.exapmleMethod(java.lang.String,java.lang.String) HTTP.REQUEST: org.apache.catalina.connector.RequestFacade@176f3f86 HTTP.CONFIG: org.apache.catalina.core.StandardWrapperFacade@8b3826f org.apache.cxf.transport.https.CertConstraints: null Accept: */* org.apache.cxf.message.Message.PATH_INFO: /example-service/v1/service/method org.apache.cxf.message.Message.BASE_PATH: /example-service/ org.apache.cxf.message.Message.IN_INTERCEPTORS: [org.apache.cxf.transport.https.CertConstraintsInterceptor@413849df] org.apache.cxf.message.Message.QUERY_STRING: accesskey=xxxxxxxxxxxxxxxxx&token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx HTTP.RESPONSE: org.apache.catalina.connector.ResponseFacade@5679f0ec org.apache.cxf.security.SecurityContext: org.apache.cxf.transport.http.AbstractHTTPDestination$2@5fb8424e org.apache.cxf.request.method: DELETE org.apache.cxf.async.post.response.dispatch: true org.apache.cxf.configuration.security.AuthorizationPolicy: null org.apache.cxf.message.MessageFIXED_PARAMETER_ORDER: false org.apache.cxf.transport.Destination: org.apache.cxf.transport.servlet.ServletDestination@3a093ffa http.base.path: http://example.com/example-service Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryhogehoge org.apache.catalina.core.ApplicationContextFacade@354753da jaxrs.template.parameters: {FINAL_MATCH_GROUP=[/]}
RDSのmysqldumpで「Got errno 28 on write」
mysqldumpで大量データのダンプを取っていたら、
mysqldump: Got errno 28 on write
と言われてエラーしてしまった。
ぐぐると、ディスクがパンパンだから/tmpをrmして!とか書いてある。
でもRDSなのでrmできない...
と思ったら、パンパンなのはmysqldumpを実施してるクライアントのディスクだった。
というわけで、言われたとおりクライアントの不要なログ消したら直った。
あらやだ。
AWS SDKで、S3のバケット指定がうまくいかない
バケット名にドット(ピリオド)いれてませんか?
static final String BUCKET = "hoge.org"; AmazonS3Client client = new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey)); client.setEndpoint("s3-ap-northeast-1.amazonaws.com"); client.setRegion(Region.getRegion(Regions.AP_NORTHEAST_1)); URL url = client.getUrl(BUCKET, "file"); // 期待してる値 => https://s3-ap-northeast-1.amazonaws.com/hoge.org/file // ところが!! => https://hoge.org.s3-ap-northeast-1.amazonaws.com/file
バケット名にドット(ピリオド)が入っていると、ドメインとして
扱われてしまうようです(aws-java-sdk 1.6.3で確認)。
バケットをドメインじゃなくてパスとして扱うようにするには、以下のように
します。
//java AmazonS3Client client = new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey)); client.setS3ClientOptions(new S3ClientOptions().withPathStyleAccess(true)); //php $client = new AmazonS3(); $client->path_style = true;
Apache + mod_sslで無駄足ふんだメモ
だっふんだ
ssl.confの設定方法は素晴らしい資料が星の数ほどあるので触れません。
ここでは、その素晴らしい資料に目を通してもなお、設定でしくじって
2時間くらい費やした残念な人のメモを残します。
環境はEC2(Amazon Linux)です。
ホスト名を変えよう
[warn] RSA server certificate is a CA certificate (BasicConstraints: CA == TRUE !?) [warn] RSA server certificate CommonName (CN) `ip-10-XX-XX-XX' does NOT match server name!?
ホスト名が申請したコモンネームと違うと、ログに上のような警告がでます。
同じにしときましょう。
セキュリティグループは大丈夫ですか
ポートあけてないの、気付くまでに相当かかりました。
443 Listenして気が済んだみたいなかんじになっていました。
このたったふたつで時間をかけてしまいました。
反省を込めてブログで晒しておきます。