僕とは関係の無いシステムが不具合を起こしていて、その原因調査にピンチヒッターとして駆り出されていたんだが、それが分かんないの。
ロジック的には正しい……はず!!
しかし、マルチスレッドで動かした時、最初に動いたスレッドは正常で、後に動かしたスレッドはエラーになる。
って聞くとマルチスレッドの競合だと思うでしょ?
違うんだなぁ~。
謎の不具合
エラーというも特殊で、同じSQLでSELECT文を発行しているのに、正常の時は値が取れるのに、エラーの時はNULLになる。DBに絶対値は入っているんだよ? でもPHPの変数に入る値はNULL。
こうなったもうバイナリ電文までチェックしたよ。
すると、電文上は明らかに値を受け取っている。
でも変数に入る値はNULL。
変数にセットしている処理はどこなのか、とオープンソースのフレームワークをソース解析して位置を特定するものの、最初からNULL。
つまり、「変数に値が入る/入らない」の分岐はMySQLドライバーの中で発生しているのよ。
整理すると、この不具合は、
- PHP
- MySQL
- MySQLドライバー
この三者間の相性みたいなもので発生する。
MySQLからのレスポンス電文が
010010010010100101010010100000__
だとすれば、MySQLドライバは本来青の場所のバイト配列を読み込むべきなのに、実際には何も無い赤の部分を読み込んでいる。
だから結果がNULLになる。
不具合はPHP本体を構成するC言語の中!!
もしくは電文ヘッダーのポインター値がズレるというMySQLのバグ。
ってところまで特定したのが今週4日間の作業。
って、こんなん知らんわ。(´・ω・`)
ちなみに、存在しないポイントを読み込む発動条件はキャッシュから値を読み込んだパターンの電文の時と分かっていて、キャッシュをOFFにすると、確かにエラーは起きない所まで確認出来た。
脳がオーバーヒート
いやぁ、こうなってくるとマジ頭がバーストしたわ。風呂の中でも夢の中でも頭がこの件を考えているから、常に覚醒状態になっちまうのよ。
身体は寝ていても脳は寝ていないような状態だった。
けど、ここまで特定してやっと脳が認めたのか、ようやくスッキリ眠れたわ。
来週はドライバーのバージョン上げるか、MySQLのパッチを当ててみるか、ってところを検討するはずだけど、
結局はキャッシュをOFFにすることで回避するという着地になるだろうな。
やれやれだぜ。(´・ω・`)
0 件のコメント:
コメントを投稿