読者です 読者をやめる 読者になる 読者になる

この日記は私的なものであり、所属会社の見解ではありません。 GitHub: takahashikzn

MariaDB-10.2.4で、カスケード削除とクエリキャッシュ絡みのバグを発見

MariaDB-10.2.4がリリースされています。これは正式リリース候補版と言うことで、早速検証してみたところ、バグを発見。


僕がぶち当たった現象とは、以下のようなものです。

  1. テーブルParentとChildには親子関係があり、Childが親を指す外部キーにはカスケード削除が設定されている
  2. Childを複数件SELECTする
  3. 2.でヒットした子レコードのうち任意のいずれかについて、親であるParentのレコードをDELETE
  4. 2.と同じSELECT文を実行すると、カスケード削除で消されるはずのChildが残っている
  5. クエリキャッシュをクリアして、再び2.と同じSELECT文を実行すると、カスケード削除で消えるはずのChildは消えている


ま、そのうち修正されると思うので、しばらく待つことにします。

ジャスミンソフト贄さん&クオリティスタート湯本さんとランチしてきた

先週の話となりますが、湯本さん経由で贄さんに連絡してもらい、ランチしてきました。

場所は銀座の過門香です。
ところで、この店は仕事でめちゃくちゃ重宝してます。ロケーションは申し分ないし、店のレベルも高い。 ぜひ皆様ご活用下さいませ。
ただし上野の過門香はおすすめできません。ここだけなぜか料理が美味しくない。

さて、僕自身、贄さんとは5年ぶりくらいの再会です。
近況報告から始まり、超高速開発業界の現況や我々の立ち位置、近い将来のあるべき姿に関する議論をしているうちに、あっという間の2時間でした。楽しかったです。

昨今、「業務をシステムに合わせて変えるべき」という考え方が広がっています。
あるべき姿を追求して自然とそうなるのなら良いですが、業務システムを作るコストが掛かりすぎるから仕方なく業務を変えるというのは絶対にダメです。

僕は、業務システムの責務はその会社の独自ノウハウ(≒業務のやり方)の効率を最大化することだと思っています。
そして超高速開発の技術を使えば、開発コストは問題では無くなる。だからとことん細かいところにまで、こだわっていい。 そうすると、業務システムの大小様々なニーズにどれほど対応できるか。これが超高速開発ツールの善し悪しを決める重要なポイントになってきます。

クラウド対応とか正直どうでもいい。お客さんにとって大事なのは中身(業務システムの機能性)であって、箱モノ(運用環境)には一切興味ありませんので。 ゴミみたいな業務システムがあったとして、それをクラウド化したら使い勝手は上がりますか?ならないでしょ。

また、いわゆる業務テンプレートが充実しているかどうかという観点は本末転倒です。そもそもテンプレート化できる業務なら既存のパッケージがある。それを買って使えば充分です。

この観点においてWagbyは、市販されている超高速開発ツール製品の中では最も完成度が高いと思います。

ちなみに言っておくと、ウチのMOD99も同レベルに到達しています。
「ホントかよ?」と思ったなら湯本さんに聞いて頂ければ懇切丁寧に説明してもらえますので、そちらへお問い合わせ下さい。(丸投げ)

外国製の製品ははっきり言ってダメです。国内の中小零細向けの業務システムには全く合いません。
とある有名な外国産製品の事例発表会で「超高速開発でプロジェクト完遂!画面カスタマイズは一切認めないという条件付きだけど」という話を聞いたときはズッコけました。

それは一体誰のためのシステムなんですかね…?

贄さんの会社には近頃大きな動きがありました(大きな会社に買収された)。
買収によって、ジャスミンソフト自体はむしろWagbyの開発に集中できるということで、オファーをほぼ即決で受けたとのこと。
製品の進化がスピードアップするわけです。ウチも負けていられません。

MariaDB-10.1.21が起動しない→SELinuxの問題

つい先程、MariaDB-10.1.21にアップデートしたらmysqlが起動しなくなりました。以下のようなエラーになります。

# service mysql start
Starting MySQL.170120 15:39:55
170120 15:39:55 mysqld_safe Logging to '/var/log/mysqld.log'.
170120 15:39:55 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
/usr/bin/mysqld_safe_helper: Can't create/write to file '/var/log/mysqld.log' (Errcode: 13 "Permission denied").       [FAILED]

これはマズい。非常にマズい。

というわけでググってみたら、こういうページがヒットしました。 http://www.rootusers.com/how-to-fix-mariadb-10-0-29-selinux-update-failure/

内容を抜粋すると、

Great, so it’s an SELinux issue.

というわけで、SELinuxの問題のようです。

上記ページではCentOS7で発生したと書いてありますが、僕の手元では一部のCentOS6のみで発生し、CentOS7は問題なく起動しています。

  • 僕の手元のCenOS7ではmysqld_safe_helperを用いた起動ではなかったために、問題が起きないのだと思われます。
  • 同じCentOS6でも、問題が起こる場合と起こらない場合があるようです。どちらもmysqld_safe_helper経由での起動ですが、何が違うのかは不明。

解決方法 → mysqld_safeのSELinuxコンステキストを変更

上記ページによると、解決するには

# ausearch -c 'mysqld_safe_hel' --raw | audit2allow -M my-mysqldsafehel
# semodule -i my-mysqldsafehel.pp

を実行せよとあります。とりあえず実行してみるとこうなりました。

bash: audit2allow: command not found

ナンテコッタイ。というわけで

yum install policycoreutils-python

を実行したのですが、

================================================================
 Package                                   Arch       Version                    
================================================================
Installing:
 policycoreutils-python          x86_64    2.0.83-30.1.el6_8
Installing for dependencies:
 audit-libs-python                  x86_64     2.4.5-3.el6 
 libselinux-python                  x86_64     2.0.94-7.el6
 libsemanage-python            x86_64     2.0.43-5.1.el6
 setools-libs                           x86_64     3.3.7-4.el6           
 setools-libs-python              x86_64     3.3.7-4.el6

Transaction Summary
===============================================================
Install       6 Package(s)

という風にいろいろインストールされてしまうので、なんか嫌な感じ。

余計なものをインストールせずに何とかならんのか。 というわけで、まずは当該ファイルを見てみます。

# cd /usr/bin
# ls -Z mysql*

するとこうなりました。

# ls -Z mysql*
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysql
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysqlaccess
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysqladmin
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysqlbinlog
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysqlbug
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysqlcheck
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysql_config
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysql_convert_table_format
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysqld_multi
-rwxr-xr-x. root root system_u:object_r:mysqld_safe_exec_t:s0 mysqld_safe
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysqld_safe_helper
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysqldump
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysqldumpslow
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysql_embedded
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysql_find_rows
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysql_fix_extensions
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysqlhotcopy
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysqlimport
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysql_install_db
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysql_plugin
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysql_secure_installation
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysql_setpermission
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysqlshow
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysqlslap
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysql_tzinfo_to_sql
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysql_upgrade
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysql_waitpid
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       mysql_zap

はい、mysqld_safeだけSELinuxのコンテキストが違いますね。 そこで、おもむろに

# chcon system_u:object_r:bin_t:s0 mysqld_safe

とやってみると…

# service mysql start
Starting MySQL.170120 15:54:04 mysqld_safe
170120 15:54:04 mysqld_safe Logging to '/var/log/mysqld.log'.
170120 15:54:04 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql            [  OK  ]

この通り無事に起動したのでした。こやつめ、ハハハ。

まあ15分ほどで解決できたので良しとします。

dracutが古いカーネルのinitramfsを勝手に作る

いつからかそうなったのかは覚えていないのですが…

新しいバージョンのカーネルをインストールすると、なぜか古いカーネルバージョン(しかもアンインストール済み)のinitramfsも作ろうとするようになっていました。

で、そのうち/bootに壊れたinitramfsファイルを大量に書き込み過ぎて容量を使い果たし、dracutが強制停止します。


それはまだいいとしても、今まさにインストールしたバージョンのinitramfsを作る前に止まってしまうので、OSがブートできなくなるという大問題が起こるわけです。

回避法→古いカーネルモジュールを手動で削除

dracutがターゲットにするカーネルのバージョンをどこで判定しているのか調べてみたのですが、 設定ファイル等ではないようです。

  • /etc/dracut
  • /usr/lib/dracut
  • /usr/system/dracut

この辺をgrepしてみたのですが何も出てこず。 もしやと思い、/lib/modulesを見てみるとそこには古いカーネルモジュール(のディレクトリ)が大量に残っている。こいつか犯人は。


というわけで、手動で古いモジュールを消すと、勝手にinitramfsを作る問題は解消されました。

EclEmma-3.0.0に更新したらエラー発生

本日、EclEmmaのアップデートが来ていたので更新してEclipseを再起動すると、意味不明なエラーが出てEclEmmaを使用できなくなりました。

次のようなエラーが発生します。

!MESSAGE Invalid input url:platform:/plugin/com.mountainminds.eclemma.ui/icons/full/eview16/coverage.gif
!STACK 0
java.io.IOException: Unable to resolve plug-in "platform:/plugin/com.mountainminds.eclemma.ui/icons/full/eview16/coverage.gif".
    at org.eclipse.core.internal.runtime.PlatformURLPluginConnection.parse(PlatformURLPluginConnection.java:61)
    at org.eclipse.core.internal.runtime.FindSupport.find(FindSupport.java:290)
    at org.eclipse.core.runtime.FileLocator.find(FileLocator.java:152)
    at org.eclipse.jface.resource.URLImageDescriptor.getFilePath(URLImageDescriptor.java:216)
    at org.eclipse.jface.resource.URLImageDescriptor.access$2(URLImageDescriptor.java:208)
    at org.eclipse.jface.resource.URLImageDescriptor$URLImageFileNameProvider.getImagePath(URLImageDescriptor.java:53)
    at org.eclipse.swt.internal.DPIUtil.validateAndGetImagePathAtZoom(DPIUtil.java:407)
    at org.eclipse.swt.graphics.Image.<init>(Image.java:684)
        ...

プラグインソースコードを読んでみたのですが原因は分からず。


その次にworkspace/.metadataの全ファイルを"com.mountainminds.eclemma.ui"でgrepしたら答えがわかりました。


解決方法

EclEmmaのタブを閉じて開き直せばOK。

EclEmma3.0から、プラグインのIDが変更になった(com.mountainminds.eclemma→org.eclipse.eclemma)ことにより、Eclipse内部のUIキャッシュの整合性が崩れたことが原因でした。

Tomcat-8.5.8以降ではHTTPパイプラインが動作しない

弊社はSeleniumを用いたガチなE2Eテストを全ての受託案件で実施しており、 CI環境では24H365Dで膨大なSeleniumスクリプトが動いています。


つい先日、CI環境のTomcatのバージョンを8.5.8に上げた所、意味不明なエラーが出てテストが失敗するようになりました。 こんな感じ。

10-Dec-2016 15:54:56.761 INFO [http-apr-8080-exec-2] org.apache.coyote.http11.Http11Processor.service Error parsing HTTP request header
 Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.
 java.lang.IllegalArgumentException: Invalid character found in method name. HTTP method names must be tokens
    at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:417)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:667)
    ...

はい?何?と思ってHTTPログを見てみると、当該エラーが発生したHTTPリクエストは次のようになっています。

127.0.0.1 - - [10/Dec/2016:15:54:56] "GET /foo.js HTTP/1.1" 200 123  ←普通の応答
127.0.0.1 - - [10/Dec/2016:15:54:56] "-" 400 -    ←なにこれ??

で、現象としてはJSファイルのダウンロードのHTTPリクエストが失敗しているために、画面が正しく動作せずテスト失敗になるようです。


結論→FirefoxのHTTP PipeliningをOFFにしたら治った

色々試行錯誤してみたのですが、結果としてはFirefoxのHTTP PipeliningをOFFにしたら治まりました。

HTTP PipeliningはデフォルトでOFFになっているのですが、 「もしかしたらテスト実行が早くなるかな―」と淡い期待とともにONにしていたものです。

Tomcat-8.5.6までは何の問題もなく動作していたわけなので、「Tomcat-8.5.8以降ではHTTPパイプラインは動作しない」ということになります。(8.5.9でもダメだったので)


誰もHTTPパイプラインなんて使っていない?

Wikipediaによると(wikipedia:HTTPパイプライン)、

近年のウェブブラウザでは、Prestoを搭載していた時代のOperaのみがパイプライン化を完全に実装し既定で有効としていた。他のブラウザは、パイプライン化を実装しているものの問題があることから既定では無効化していた、あるいは実装していない。

だそうです。

自分の精神をコピーしたら何が起きるのか

こんな増田が話題になってます。

anond.hatelabo.jp

僕も先月に「ディアスポラ」を読み終わったところだったのでちょうどよいネタ。

ディアスポラ (ハヤカワ文庫 SF)

ディアスポラ (ハヤカワ文庫 SF)

この作品はマジで面白い。序盤はやや難解ですが、傑作だと思います。

  • 一人の「個人」であることを満たす要件とは何か?
  • 誰かが「存在する」とはどういうことなのか?

についての一つの考え方を垣間見ることが出来ました。


もし機械の脳が実現したとして

あなたは不治の病に侵されて余命半年とします。「なぜ俺がこんな目に…」と世界を呪う日々。

そんなある日、聞いたこともないような小難しい名称の研究所から、一人の研究者がやってきました。

「機械の脳を実用化しました。精神をコピーすれば不老不死も可能ですし、コピー先は外見があなたと瓜二つの生体ボディです。ぜひ被験者になって下さい。」

あなたは大喜び。

自分の精神をコピーすれば病を克服!むしろ永遠の命がこの手に!やったー!!

ぜひ俺を被験者にしてくれ、と二つ返事をするわけです。


しかし現実は甘くない

そんなハッピーエンドにはならないわけです。

精神をコピーしたら何が起きると思いますか?


…さて、コピー作業が終わり、麻酔が切れて目覚めたあなたが見たものは2つ。


  • 「相変わらず余命半年のままの哀れな自分」
  • 「他者から見たら完全に自分そのものに見える、自分ではない誰か」


ただそれだけ。


外見、立ち振舞い、記憶が完全に自分と同じなら、他者から見たらそれは実質的に、あなた以外の何者でもありません。

ここにあなたは病気を克服し、永遠の命を得ました。おめでとうございます。

ただし他者から見たら。


あなたはそのコピーを恨むでしょう。

「あいつは俺が過ごすはずだった幸せな日常を取り戻してやがる…本当の俺はここだ!!あいつはニセモノなんだ!!」

という具合に。


さて、ではこのコピーは何者なのでしょうか?


こんな観点の作品、誰か教えてください

ディアスポラはそういう話ではないんですよね―。

色々探してみたのですが、僕のグーグル力では見つけられませんでした。


個人的に近いと思っている作品

SOMA

Steamのホラーゲームです。 ややネタバレですが、物語の終盤で、上記のような葛藤に主人公は直面することになります。

store.steampowered.com

弟者兄者のプレイ動画はこちら。 www.youtube.com

AIの遺伝子

山田胡瓜さんのマンガです。ITmediaの記者から漫画家へ転身したという変わった経歴の持ち主です。

試し読みできる第1話がそんな感じの、自我同一性に関する話です。

追記

この日記を書いた2時間後にふと「機械の脳」でググったら即出てきました。

なんかすいませんでした。

detail.chiebukuro.yahoo.co.jp

更に追記

順列都市」を読み始めたのですが正にそんな話でした。

順列都市〈上〉 (ハヤカワ文庫SF)

順列都市〈上〉 (ハヤカワ文庫SF)