- アクティブ画面キャプチャ+ファイル保存:❖+Alt+PrtSc
- 全画面キャプチャ+ファイル保存 :❖+PrtSc
- 指定範囲キャプチャ(ファイル保存しない) :❖+Shift+S
- クリップボード履歴 :❖+V
※2 これらのショートカットキーはWin10のバージョンによって使えないものがあるようです。







CentOSの話だが、-Gオプションを付けて定期的に別ファイルに書き込む事が出来る(簡易的なファイルローテーションで削除はされない)。
この際、-Zでユーザーを指定しないとローテーションする際にPermission deniedが出て異常終了してしまう。
約3.0GBのファイルを置換をした。
対象の置換前文字列は、数十行。
sedコマンドを一行ずつ並べて行ったが、
余りに時間が掛かるため、sedコマンドオプションの-fを使用した。それでもかなり時間掛かったが、-f付きの方が早かった。
SELECT *
FROM (
SELECT *
, ROW_NUMBER OVER (PARTITION BY id) AS row
FROM tmp_table
) as t
WHERE row >= 2;
または、
SELECT id
FROM tmp_table
GROUP BY id
HAVING count(*) >= 2;
[事象1]
pg_dumpコマンドで出力したデータを別のサーバーのDBにpsqlコマンドでリストアしたら重複キーエラーが発生した。
補足:実際はレコードのinsertは成功、つまり重複レコードが入ってしまった。その後の主キー制約の作成で重複キーエラーが出力されていた。
postgresのダンプデータの順序は、レコードをcopyした後に主キー制約作成(インデックス作成)という順序になっているらしく、この様な状態となった。
これだけ聞くとPostgreSQLのダンプのバグのように思えるが、実際は違うようだ。
[調査]
元のDB(pg_dumpを実行したDB)を見ると元のDBが壊れていた。
事象としては以下のselect文で結果が違うと言う不可思議な現象だった。
①whereで主キー指定したselect 文
②whereで主キー以外を指定したselect文
これらの結果は一緒になる想定だったのだが、実行すると結果が違って、②の方が数十行多く出力されていた。
このテーブルには、主キーが設定されていたにも関わらず、明らかに重複キーの状態でテーブルに登録されていた。
これによりインデックスと生テーブルに不一致が発生したと判断した。
つまり、インデックスは正しいが、テーブルには重複レコードが存在している。
因みにpostgresはupdateする際は、追記型つまり内部で行をコピー&元の行に削除フラグをたてているはず。この削除フラグの変更が失敗したのではないかと思う。
元のDBが壊れた理由は不明。訳あって調査出来ず。
[復旧]
2回ほど復旧を実施した。もとのDBは運用環境のため、触る事が出来ない。そのため、リストア先DBの復旧を行った。リストア前、リストア後の復旧を行った。とある事情により、それぞれ違う方法を使用した。
(a)ダンプデータを修正して再リストア
中途半端にリストアしたDBは破棄して、ダンプデータをviで修正(重複レコード削除)して再度リストア。
この方法はダンプデータが巨大だとかなり時間がかかる。と言うか、でかすぎるとエディタがまともに動かなくなる。一応、ダンプデータは5GB程度だったかな?なのでこれでも復旧出来た。また、バイナリダンプの場合は使用出来ない。
(b)中途半端にリストアされたDBを復旧
select row_number over partition byで重複レコードを探す。group by having countでも良い。その結果から残したい行のinsert文を作成。
で、重複レコードを二行とも削除(主キー制約作成失敗しているため、A5では片方ずつの削除が出来なかった)。
で作成したinsert文を実行。その後、失敗していた主キー制約を作成して復旧完了。こちらは復旧の仕方が正しいのか不安がある。
過去にあった話2件程紹介します。
どちらも仮想マシンです。物理PCでMACアドレス重複はほぼ有り得ないでしょう。OS側でMACアドレス変更出来たりしますし、ROM焼きすれば物理MAC変えられますが、業務でこれらの事態に遭遇することは無いでしょう 。
■1件目
サーバーのセキュリティー点検とかで、お客さんのセキュリティー部門がデータセンターのサーバーを使用してたのですが、何故かサーバーに繋がらないって言われました。詳細は教えて貰ってないですが、SSH接続か、ブラウザで接続出来なかったのだと思います。
既に環境構築終えて、運用直前だったので報告を聞いて少し焦りましたが、何度も事前に接続していましたし、遠隔でも接続には問題無かったサーバーです。
結局、セキュリティー部門のミスで、仮想マシンのMACアドレスが重複してたせいで、接続出来なかったとのことです。
多分持ち込んだノートPC内の仮想マシン2つが重複したのだと思いきます。
これ以上の情報が届きませでしたので、詳細は不明です。
確かに仮想マシンならMACアドレス重複は可能です。仮想マシンの設定でMACアドレスを指定できます。しかし、どうしてそのような事態になったのでしょうか?
完全にカンで書きますが、セキュリティー部門は案件ごとに仮想マシンを使い分けてたのでは無いでしょうか?社内のルールで案件ごとに分けるよう決まってるという推測です。会社によっては、あるネットワークに接続したOSを別のネットワークに接続するのを、禁止しているとか有り得そうです。
その時私が携わった業務は、お客さんにとっては新規案件でした(お客さん側には沢山の既存案件が有ります)。上記の推測が正しいなら、ノートPC内で新しく仮想マシンをコピーしたと考えられます。VMWarePlayerなら当時はVMコピー後、起動時にコピーしたか、移動したか聞かれたはずです。で移動したと答えると確かMACアドレスを変更しなかったと思います(最近VMWarePlayer使ってませんので、最新版は分かりません) 。
更にコピー元のVMを何故か起動してしまってコピー元とコピー先のVM間でMACアドレス重複してしまったのかな?かなり強引なこじつけですね。
ん?
1人で作業してると思い込んでましたが、2人で作業してたなら、2人のPC間でVMコピーして、MACアドレス重複してた可能性もあるのか・・・。それなら二台同時にVM起動してるのも納得が行きます。サーバー系の作業で、1人作業は有り得ないです。此処まで書いて覆すようですが、そっちの方が可能性高い気がしてきました。
何時もそうですが、お客さん側のミスって、全然情報来ないので何が起こったか真相は不明ですよね。こちらがミスすると、細かいとこまで全部報告して、とてつもなく怒られるのに。
上記の推測が正しいか分かりませんが、VMのコピーは気をつけるようにしましょう。
■2件目
こちらは後輩の話です。
知識や技術は全然無い後輩でした。ある日、上司から後輩の進捗が悪いので、見てこいと言われました。後輩に聞いたらネットワーク接続出来ないとの事でした。
WindowsにVirtualBox入れて、その上にLinuxだったかな?を入れて更にその上に、業務特有の専用VM、専用OSを入れてました。以下のような構成です。
専用OS
専用VM
Linux
VirtualBox
Windows
ホストPC
一番下のWindowsから一番上の専用OSに通信(業務特有の通信)出来ませんでした。一応全てNATにはなってたので(後輩は何故NATが必要かも解って無かったと思います)、通信出来てもおかしくはなかったのですが、駄目でした。
最初に私が確認したのはpingです。
確かLinuxと専用OSの間は問題有りませんでした。(結構前の話なので、曖昧です。すみません。)
次にWindows、専用OS間のpingを試すと片方向のみpingが通りました。Windowsから専用OSはOKで、専用OSからWindowsが駄目でした。
じゃあ間違くWindows側のファイアウォールだろうとWindowsとセキュリティーソフトの設定見直ししましたが問題有りませんでした。
此処で行き詰まりました。
最初から試すべきでしたが、試行錯誤してる中で、WindowsとLinux間もpingを試して、WindowsからLinuxはOKで、LinuxからWindowsが駄目でした。ということで、専用VM側は関係無いと分かりました。
これでNGの範囲が大分限定されました。が、普段WindowsとVirtualBox上のLinux間の通信異常なんて有り得ないので、やはり苦戦しました。
何度か繰り返し設定見直ししていると、Windowsでipconfigを打った時にMACアドレスがふと目に留まりました。どこかで見たと思ったら、LinuxのMACアドレスだったのです。
後輩に聞いたら、要領を得ない何とも曖昧な回答でした。ごまかそうとしてたんだと思います。多分後輩がVirtualBoxの設定でMACアドレスを変更したのでしょう。それを何故かWindowsのものと一緒にしてしまったと。
正直最初から専用VMと専用OSを疑ってました。これらの実績は圧倒的に低かったためです。Windows、VirtualBox、Linuxの間で通信異常なんて有り得ないと思い込んでいました。
解析する時は思い込んでしまったら駄目ですね。全て怪しいと考えて作業しなければなりません。
多くの日本のIT企業はウォーターフォール開発を使っていると思います。(実際はアジャイルやプロトタイプも多いでしようが)。
ウォーターフォールの場合は、前の工程のアウトプット(成果物)が次の工程のインプットになります。建前としては前の工程に戻るという事は無いため、各工程の成果物は、品質の高いものになっている必要があります。
そのため、各工程では念入りに成果物の作成、レビューをします。かなり時間を費やすわけです。で、各工程のレビューはお客さんレビューも実施します。
ここで良く有るパターンが、各工程のレビューを自社レビューのみとしてしまうパターン。これをしてしまうと客先試験で、大ドンデン返しを食らう事があります。客先試験は大抵の場合、一番最後の工程なので途方も無い手戻りが発生する事があります。前に述べたとおり、各工程ではかなりの時間を費やすのです。それを全部ではないにしてもやり直す訳です。
そのため、各工程の成果物は、その都度お客さんにレビューしてもらい、こう言った手戻りが無いようにする必要があります。これが、正しい開発の在り方と思ってます。
ここで問題があって、お客さん側の都合で、仕様書・設計書レビューを試験後にやることが、決められているパターンや、忙しいとの理由でレビューを断られたり、試験後にして欲しいと言われて後回しにされてしまう事があります。そうしておきながら、お客さん試験でいざ使ってみると、こうじゃないと指摘をして、修正しろと言って来ます。
本来、仕事をサボった(ウォーターフォールの定石通りしなかった)のはお客さん側なのですが、それでもお金を貰っている以上やるしかないのです。こうなると前述の通り、かなりの時間をかけているわけですから、工数つまりお金の無駄使いとなってしまうわけです。なので、できることなら各工程でレビューをしてもらうよう努める必要があります。
更に言うと、各工程の最後にレビューをしてもらうだけではなく、週2位で打ち合わせをして、軽く成果物のレビューをしてもらうと大きく方向をズレること無く、方向の微調整が効きます。1チーム4人として、1人1日3ページ(実際はもっと作れるはず。)作れば、週2で打ち合わせするには、十分な量の資料が作成出来ます。
自信が無いなら叩き台レベルと言って作成完了してない旨匂わせます(これはお客さんによって未完成が気に食わないって人もいるでしょうが)。ここで言いたいのは、試験の最後に見てもらうより、各工程の最後、各工程の最後で見て貰うより、週単位で見てもらう。つまり、細かく刻んだほうが大きく道を反れることが無い※と言う事です。勿論、各工程の最後、お客さん試験も実施します。
※レビューア(成果物のレビューをする人)、試験者が違う場合で、2人の意見が違う場合、厄介なことになるのことがあります。
当然と言えば当然ですが、会社に入ると、好きな業務に就くことは出来ません(場合によっては可能でしょうが)。
私の場合、プログラミングがしたくてSEを志望し、IT企業に入社しましたが、数年間試験業務でした。その後、開発に携わることも有りましたが、インフラ(環境構築)や試験業務が多いです。
会社を辞めるという選択肢もありますが、自分のコミュニケーション能力の低さ、試験業務しか経験が無い点を考えると転職は中々難しいです。
ということで、毎日のつまらない試験業務でモチベーションを保つ工夫をしていました。例えば、Excel VBAやVBS、bat、shスクリプト、PowerShell、TeraTermマクロを使って試験や日々の作業の自動化です。
特にPowerShellはWindowsVista以降は標準で入っており、.NETの標準ライブラリーがある程度使え、簡易デバッガも入っているので導入の手間がありません。
ただ、普段の試験や作業を遅らせて良いわけではないので、先輩・上司に確認のもと、少しずつ作成&改良していきます。
人それぞれ興味は違うので、方法はそれぞれ変わると思いますが、日々の作業がつまらなくても、こういった工夫でモチベーションを保つことが、できます。
お客さんの依頼で数十万テーブル(数百万だったかも)作成した時の話です。動的にテーブルを選択するということです。
通常はやらないです。と言うか、普段の開発から逸脱したことはすべきではないです。
上司がその依頼を受け、私は設計後にそのプロジェクトに入ったので止めようが無かったのです。
PostgreSQLの開発者が、数十万テーブルを想定してるのか不明ですが、RDBの使い方としては誤りと言っていいと思います。リレーショナルデータベースと言うものを全く理解してません。リレーショナルデータベースをただのデータとして捉えてはいけません。
結論を言うと、create tableで躓く羽目になりました。テーブルが多くなれば多くなる程、create tableの速度が落ちて行ったのです。確か数十万だか、数百万テーブル作成するのに、1日程度掛かりました。あり得ないです。再構築が容易く出来ないです。また、運用開始後、列追加などが容易く出来るか心配です。
そもそも、create table文を自作する羽目になる(ツールでcreate table文を作成後、テーブル名に_1、_2、を足していく)わけで、これもあり得ないです。通常は、visualstudioやeclipse、そのほかのツールで自動生成し、速攻DBに投入します。(初回起動時に生成する方法もあります。)
これでは、通常通りの開発が出来なくなります。元々、そのプロジェクトは破綻してましたので、どれ程の遅延を招いたか定かでは有りませんが、確実に開発速度を落としていました。
この話に限らず、通常の開発から逸脱したことは避けるべきです。
お客さんの都合により、複数の会社が同じWebアプリ内の機能を作成する事があります。もちろんそれぞれの会社の作成している機能は別物です。
OutOfMemoryErrorや原因が不明なエラーが発生した場合にどの会社が解析するのかと言う問題があります。
お客さんが事前にどの会社がやるのか決めてくれている場合は良いんですが、そうでない場合が厄介で、本来であれば契約に従う必要があり、契約書に無いことをやってはいけません。が、どの会社も契約してない場合は誰かがやるしかないんです。
しかし、誰もやろうとしないんですよね。
恩を売る、または勉強と割り切って自分で実施しましょう。やって見ないといつまでも機会がありません。こういうバグの解析は稀にしかありません。なぜなら、かなり出来る人間が毎回解析するため。年次が高くなっても出来ないと困ったことになります。プロジェクトを任されて、外のメンバーは1~3年目のみとか詰みます。
■解析方法
JavaやC#のExceptionがログファイルに出ていれば、ソースコードのファイル名と行番号からエラーが特定出来ます。
今回はそうではなく、良く分からないエラーの場合です。
良く分からないエラーって何です?って思いますよね?
例えば、定期処理が動かなくなったとか、画面にもログファイルにも何も出てないが操作が出来ないとか、操作が途中で止まるとか、砂時計のままとか、少し違和感があるとか、異常に遅いとか、・・・。
Exceptionが出てない場合はエラー箇所が分からないため、ソースコードのどこに問題があるのか分からなかったりします。この場合、見るべきことが沢山あります。主なものを以下に記載します。
●Javaの場合
・ログファイル
エラーが発生したと思われる時間帯の前のログなど。ログファイルは膨大なのでgrep、egrep、head、tail、unique、cut、sort、sed、awk、viewなどのテキスト関連のコマンド、サクラエディタ※1の正規表現置換、ブロック選択、Excelなどを駆使してエラー箇所を絞り込み、エラーの特定、そこまで行かなくても何の処理が動いてたかを把握して解析の取っ掛かりにしたりします。
・Catalina.out
まずはOutOfMemoryErrorでgrep。Catalina.outも大量にログが出てる場合があります。なのでログファイルと同様の解析をしたりします。皆なんでCatalina.outに余計なログ出すかなあ?Catalina.outはOutOfMemoryとかErrorの子クラスだけにして欲しい。それ以外はロガーに出してくれ。
・リソース使用量
・sar
サーバーのcpu使用量。グラフ化すれば、おかしくなり始めた時間帯などを特定出来ます。
・top
現在の各プロセスのCPU使用量、メモリ使用量。
・ps
スレッド数、ファイルディスクリプタ数などを調べられる。出来れば事前に定期観測しておく。
・free(Javaでは余り見ない)
サーバーのメモリ使用量。
・iostat、vmstat記録してたが何に使ったっけ?
・コネクション数
DBコネクション数が限界に達してないか?定期的に記録しておきましょう。何のコマンドだったな?vmstat?netstat?
・jconsole
JavaのCPU使用量、ヒープ使用量、メモリ使用量。
・jstat
ヒープ使用量定期観測。事前に仕掛けておく。
・ヒープ内の各クラスのメモリ使用量。コマンド名は何だったかな?
メモリリークの場合、どのクラスがリークしてるか分かるので必須です。特に正常時と異常時の比較、起動直後と時間経過後の比較をすると、あっさり原因特定出来たりします。
・jstack
・スレッドの状態(最近はスレッド数が多くて一苦労)
・スタックの状態
・ロック残り、デッドロックの有無
●Windowsの場合
・タスクマネージャー
windows用。列追加すると色々見られる。プロセスのCPU使用量、メモリ使用量、ファイルディスクリプタ、スレッド数、GDIオブジェクトなどのリーク。
・リソースマネージャー
タスクマネージャーより詳しく見られるらしい。余り使ったこと無い。
・typeperf
プロセスのCPU、メモリ使用量、ファイルディスクリプタ、スレッド数などを定期観測。事前にしかけておく。何れも増え続けているものは注意。typeperfはGDIオブジェクトが記録出来ない。何でだ?
●DBがある場合(製品によって確認方法が違うのでざっくり記載。)
・トランザクション残り
デッドロックやトランザクション残りの特定。
実行中のselect文が見られる場合があり、問題のある機能が特定出来る。また、手動でinsert文実行時にトランザクション途中でウィンドウを閉じて、トランザクションが残ってしまい、他の機能が動かない問題などの特定。トランザクション残りって呼んでますが、本当は何て呼ぶんでしょう?
・ロック残り
トランザクション残りとほぼ同じ。デッドロックの特定。
怪しい箇所は時系列順にメモして、最初のエラーを特定します。リーク系は最初ではなく、時系列でみます。
また、正常時との比較も重点です。
※1 他のエディタでもいいですが、巨大なログファイルを扱える必要があります。サクラエディタは結構耐えてくれます。分割してもいいですが。