2018年10月4日木曜日

【tcpdump】Permission denied【Linux】

CentOSの話だが、-Gオプションを付けて定期的に別ファイルに書き込む事が出来る(簡易的なファイルローテーションで削除はされない)。
この際、-Zでユーザーを指定しないとローテーションする際にPermission deniedが出て異常終了してしまう。

2018年10月2日火曜日

【Linux】スクリプトファイル指定にすれば早い【sed】

約3.0GBのファイルを置換をした。
対象の置換前文字列は、数十行。
sedコマンドを一行ずつ並べて行ったが、
余りに時間が掛かるため、sedコマンドオプションの-fを使用した。それでもかなり時間掛かったが、-f付きの方が早かった。

2018年9月29日土曜日

【SQL】重複行探すselect文

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;

【PostgreSQL】【pg_rman】別サーバーにリストア

pg_rmanだと設定も復旧されてしまう。そのため、別のサーバーにリストアする場合は注意が必要。設定を復旧しない方法は未調査。

2018年9月28日金曜日

【SQL】pg_dumpしたデータでリストア失敗【PostgresSQL】

[事象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文を実行。その後、失敗していた主キー制約を作成して復旧完了。こちらは復旧の仕方が正しいのか不安がある。

2018年9月26日水曜日

【Linux】ファイルコピーで入力/出力エラー【cp】

●エラー
『cp: cannot stat `xxx': 入力/出力エラーです。』
(xxxには具体的な、ファイル名が入る)

ある日、ファイルコピーを実行したら、上記のエラーが発生してコピーに失敗した。
で、/var/log/messagesを見たら、以下のエラーが出力されていた。
『kernel: EXT-fs error (device dm-0) :  ext4_lookup: deleted inode referenced: yyy』
(yyyには数字が入る)

●fsckコマンドで復旧
【注意!!】以下のfsckはファイルが消失する可能性がある。
umount AAA
(AAAにはマウントポイントが入る)

fsck -y /dev/mapper/ZZZ
(ZZZにはボリューム名が入る。)

2018年9月23日日曜日

【Linux】【rm】 */*コマンドのオプションは-vI

rm -vI */*.txt #カレントの全ディレクトリ配下のtxtを削除。
rm -vI */*_????????.txt #カレントの全ディレクトリ配下の日付付きのtxt
rm -i */*.txt #カレントの全ディレクトリ配下のtxtを削除。


rmコマンドでワイルドカード指定する場合は危険なので、確認オプションをつけるようにする。

-iオプションの場合は全ファイルに対して確認が表示される。20ファイル以下なら-iオプションで良い。20以上なら-vIをつけて確認を表示する。

何の意味があるかと言うと、コマンド打ち込みの途中で誤ってEnterを押してしまい、更に* /*など途中にスペースが入ってしまった場合に即実行されないために入れる。-rをつけてないので大丈夫と思うが。

最近のLinuxでは、rm -rf /*は防止されているらしいが、念のためやっておく。
個人的には、オプション指定しなくても確認が出てくれるとありがたいのだが。

-vは削除したファイル名を表示してくれるオプション。誤って関係ないファイルを削除したかどうか確認する。