ちょっと硬派なコンピュータフリークのBlogです。

カスタム検索

2009-12-28

MySQL Cheat Sheet 1.0

先日、DB2 Cheat SheetなるものがDB2な人のページにアップされたので、負けじと早速MySQL Cheat Sheetを作ってみた。

A4サイズで印刷して手元に置いたりデータセンターに持っていったり額に入れて壁に貼ったりポスグレ派の人の鞄にこっそり忍ばせたり自分の枕の下に敷いたり(イイ夢見るよ!)出来るようにしてあるので是非ダウンロードしていただきたい。なお、ツッコミがあればいつでも本投稿へのコメントおよびTwitter(@nippondanji)やメール(みきやどっとおくのあっとぢぃ〜めいるどっとこむ)などで受け付けているのでお気軽にどうぞ!!

2009-12-22

MySQLバックアップ頂上決戦!! LVMスナップショット vs InnoDB Hot Backup

先日のMyNAのイベントにて、「InnoDB Hot Backup(もしくはXtra Backup)のようなツールとLVM等でスナップショットを取るのはどちらが最強のバックアップたり得るか?」という感じの内容の議論がなされていたのだが、確かにこれは答えるのが難しい永遠のテーマである。永遠のテーマだからこそ漢のロマンがある!!というわけで、今日はそれぞれのバックアップ方法について仕組みを説明しつつ私の見解を述べたいと思う。(見解≠結論ではない点には注意して頂きたい。結論を出すのは貴方なのだから!!)

2009-12-18

MySQLに纏わる10の都市伝説

誰の口から飛び出したのかは定かではないが、巷ではMySQLにまつわる様々な「都市伝説」がまことしやかに囁かれているようだ。恐らくMySQLに対する理解が低い人や、MySQLがあまり好きではない面々によってFUDっぽく言われているのだと思うが、世の中にはそのような「都市伝説」を真に受けてしまう人が居るのもまた事実であである。MySQLにおける昨今の開発スピードには目覚ましいものがあり、MySQLは性能・安定性・使い易さ共に進化し続けている。(特に先日リリースされたMySQL 5.5は性能・安定性・使い易さを両立している優れたバージョンだ!!)しかし「都市伝説」で語られることは総じて「MySQLはダメな子ちゃん」であるという烙印を押すものばかりであり、MySQLerとしてはそのような言われ無き汚名を全身全霊をもって晴らさなければならない使命を背負っている。そこで、今日はMySQLについて語られている「都市伝説」を10個紹介しよう。MySQLをよく知っている人にとっては「んなアホな!?」と思われるほど突拍子もない事ばかりなので、くれぐれもそのような根も葉も幹も細胞もないうわさを信じないで頂きたい。

2009-12-16

MySQL 5.5 厳選リンク集

現時点で出てきているMySQL 5.5関連の(MySQL 5.5の新機能を理解するのに役立つ)ページをまとめておくので参考にして頂けると幸いである。

MySQL 5.5登場

MySQL 5.5がリリースされた。「えっ?!この前5.4をリリースしたばっかりでしょ?!まだ5.4すら使ってないよ!!」と驚かれた方はご安心を。これは開発リリースモデルが変更されたためで、MySQL 5.4はこれでいったん開発終了して今後の開発はバージョン5.5をベースにして継続されることになる。バージョン5.4も5.5も「マイルストーンリリース」(以下MR)という位置づけであり、GA(正式リリース)版ではない点に注意して頂きたい。MR版の位置づけは次のようなもの。

2009-12-12

mysqldumpの出力結果をデータベースごとに分割するパッチ

先日は、mysqldumpの出力結果をawkを使ってデータベースごとに分割する方法について紹介したが、セミナーも終わったことなのでパッチを書いてみた。awkで分割するというのはUNIXユーザーの伝統芸能なので嫌いではないがまどろっこしいと感じる方も居るかもしれない。そもそもmysqldump自体がそのような機能をサポートしていれば問題ないのだから!

というわけで、興味のある人は次のバグレポートからパッチをダウンロードして試してみて欲しい。

http://bugs.mysql.com/45003

そして試した後にはフィードバックを残して頂きたい!!

パッチの適用方法は以下。

まずはMySQLのソースコードを入手する。ダウンロードサイトから最新のものを入手するか、bzrでゲットして頂いて構わない。

ダウンロードサイト:
http://dev.mysql.com/downloads/mysql/5.1.html

bzrコマンド:
shell> bzr branch lp:mysql-server
ダウンロードサイトから入手した場合は、ソースコードを展開しておいて欲しい。

次に、上記のバグレポートから、bug45003.patchというファイルをダウンロードして、ソースコードのトップディレクトリ(展開した後に作成されるディレクトリ。ダウンロードサイトから入手した場合にはmysql-5.1.41、bzrで入手した場合はmysql-server)へコピーしよう。
shell> cp bug45003.patch mysql-5.1.41
そしてパッチを適用する。
shell> cd mysql-5.1.41
shell> patch -p 0 < bug45003.patch
あとはビルドして生成されたmysqldumpを実行するだけである。パッチを適用したmysqldumpを使ってデータベースごとにファイルを作成するには--backup-basedirオプションを使う。このオプションは--databasesまたは--all-databasesオプションと併用しなければならないという制約がある。また、--tabオプションと同時に使うことは出来ない。コマンド実行例は次の通り。
shell> mysqldump --backup-basedir=/backup\
--single-transaction --master-data=2 --flush-logs\
--databases db1 db2 db3
そうすると、/backupディレクトリに6桁の数字、例えば000001というディレクトリが作成され、そのディレクトリの下にdb1.sql、db2.sql、db3.sqlという具合に「データベース名.sql」というファイルがそれぞれ作成されるという寸法である。6桁の数字のディレクトリは、既に他のディレクトリが存在する場合、次の数字が使われる。(000001が存在すれば000002が、000002が存在すれば000003が作成される。)常に同じコマンドラインでバックアップを作成できるというワケだ。

皆様からのフィードバックをお待ちしております!!

2009-12-09

ギークが己の世界観で語る、コミュニケーションが論理的になりすぎてはいけない理由。

論理的なコミュニケーションをしろと言ったりするなと言ったり、お前は一体どっちなんだ?!と突っ込みたくなるところをぐっと抑えて、まずはこの記事を最後まで読んで欲しい。話はそれからだ。

論理は手段(ツール)であって目的ではない

ある記述が論理的に正しいことは、論理的なコミュニケーションの場ではとても重要なことであり、言わば論理的であることはコミュニケーション(主に議論)を建設的なものにすることの前提条件であると言って差し支えない。理論的なことを思考するにはもの凄い集中力が必要なので、ついつい議論に集中し過ぎて「自分の主張の正しさ」だけを追求してしまい、話が噛み合わず不毛な時間を過ごしてしまうということになりがちである。人と人が何かについて話合ったり議論したりするということは、「今抱えている問題を解決したい」「建設的な意見を出し合ってプロジェクトを進めたい」などの目的があるはずであるから、「論理的な議論」というのは目的達成のための手段であるに過ぎないのである。目的を忘れて「論理の正しさ」ばかりに集中してしまうと、頓珍漢なやりとりを繰り広げてしまうことになるのである。

会話がちぐはぐになるだけならまだいい。しかし理論的な正しさばかりを追求すると本来の目的を見失うどころか、逆にとんでもない弊害をもたらすことがあるので注意が必要だ。例えばサポートエンジニアが論理的な正しさばかり追求することに白熱してしまい、

「お客様のおっしゃることはまちがっています。なぜなら、理由はxxxxxだからです。問題が解決しないのはお客様の認識が間違っているからです。」

などという意味のことを言った場合を想像してみて欲しい。かなりの高確率でクレームを頂き、クレーム対応という理不尽な世界≒地獄への片道切符を手に入れることになるだろう。そもそもサポートエンジニアの役割はお客さんの問題や悩みを解決することであって、理論的なアプローチはそのための手段でしかない。単に論理的なアプローチが効果的だから選択しているに過ぎないということである。従って極論してしまえば問題が解決してしまえば理論的な正しさなどどうでもいい。理論的な正しさを優先させてお客さんを怒らせてしまうと悲惨な結末が待っている。まさに「どうしてこうなった?」と言わんばかりの結末が・・・。

くれぐれも理論的な正しさを追求するあまり、本来の目的を見失ってはいけないのである。

論理的思考の限界

論理的なコミュニケーションを行うには論理的に物事を考える必要があるのだが、そもそもその論理的思考には限界があるということについてここで紹介したい。

ところで、理論的に正しい記述というのはどのようなものだろうか。極力誤解のないようにストレートに表現すると、「論理的に正しい記述」というのは「論理学的に正しい記述」と言い換えることが出来る。論理学的に正しいとは、ある命題(前提)から別の命題(結論)を演繹(えんえきと読む。≒論理演算)だけを用いて導出できるということだ。つまり、演繹だけで構成された記述だけが、論理的に正しい記述と言えるのである。(ただし、演繹をショートカットするための定理は用いても可)それ以外の記述はすべて論理的な記述ではない。「なんだって?!そんなバカな!?だったら論理的な文章なんて殆ど存在しないじゃないか!!」と思われるかも知れない。いや、実はまさにその通りなのである。世の中に存在する「論理的な見た目を装った文章」の99.9999%は実は論理的ではない!!と俺は断言する。殆どの文章は論理的な見た目を装って自分の主張をタレ流しているだけである、と。

そもそもであるが、論理的に正しい記述をするというのは気が遠くなるほど地道な作業である。そのことを説明するために例として演繹の代表格である「三段論法」について考えて見よう。言わずもがなであるが、三段論法とは次のようなものである。
  • Aが正しいならばBも正しい
  • Bが正しいならばCも正しい
  • よってAが正しければCも正しい
三段論法によってもたらされるものは命題A、B、Cの関係性だけである。三段論法では大前提であるAの正しさについてはどこでも言及されていないところがミソだ。三段論法を用いて何か論理的に正しい主張をするとしよう。「Aという事実がある。AならばBなので、よってCというのは世の中の真理である」と。この主張が論理的に正しいことを証明するためには、大前提のAが正しい命題でなくてはならない。果たしてAの正しさを我々はどのように証明するべきなのだろうか。

そこで登場するのが「公理」というものである。公理とは数学用語であるが、あらゆる命題を導きだすための大前提として用意された最も基本的な仮定のことであり、公理の集合を公理系という。公理を組み合わせて導き出された帰結が「定理」であり、定理の正しさは公理系によって保証されていると言える。従って、真に論理的な正しさを追求するならば、「公理からの演繹によって導き出された帰結以外は全て非論理的」と切り捨てなければならない。

ここで勘の良い人ならばもうお気づきだろう。「公理系の正しさはどうやって証明するんだ?」と。

実は完全無欠の公理系は存在しない!ということが既に天才数学者ゲーデルによって証明されている。かの有名な「ゲーデルの不完全性定理」である。不完全性定理を要約すると「完全な公理系を用いてその公理系そのものの無矛盾性を証明することはできない」ということだ。つまり、実は完全無欠の論理というのは端から存在しないということなのだ!!

な、なんだってーっ!!(AA略)

完全無欠の論理が存在しないということは、どのような命題でも論破出来るということである。よくネットで「ハイ、論破」などという表現を見かけるが、どのような主張でも論破出来ることは最初から分かっている(ゲーデルが証明した)ので「論破したよ!」などとアピールするのは全くもって無意味かつ自らの無知をさらけ出す行為であると言えよう。

従って、如何に論理的な記述を突き詰めようと思ってみても完全な論理体系というものは存在しないので、論理の正確さに固執しても仕方がないのである。

フレーム問題

論理的な思考の有効性を否定する問題がもう一つ存在する。それは俗に言うところの「フレーム問題」だ。フレーム問題とは人工知能学者が古くから直面している由緒正しき問題で、平たく言うと「人間にとってごく身近で易しい問題であっても、コンピュータを用いた演繹では解決できない問題が存在する」というものである。以下はWikipediaからの引用で、フレーム問題、つまりコンピュータが解決出来ない問題についての有名な例である。

状況:洞窟の中に、ロボットを動かすバッテリーがあり、その上に時限爆弾が仕掛けられている。このままでは爆弾が爆発し、ロボットは動かなくなってしまうので、洞窟の中からバッテリーを取り出してこなくてはならない。ロボットは、「洞窟からバッテリーを取り出してくること」を指示された。

人工知能ロボット1号機R1は、うまくプログラムされていたため、洞窟に入って無事にバッテリーを取り出すことができた。しかし、1号機はバッテリーの上に爆弾が載っていることには気づいていたが、バッテリーを運ぶと爆弾も一緒に運び出してしまうことに気づかなかったため、洞窟から出た後に爆弾が爆発してしまった。これは、1号機が、バッテリーを取り出すという目的については理解していたが、それによって副次的に発生する事項(バッテリーを取り出すと爆弾も同時に運んでしまうこと)について理解していなかったのが原因である。

そこで、目的を遂行するにあたって副次的に発生する事項も考慮する人工知能ロボット2号機R1-D1 (D = deduce (演繹) ) を開発した。しかし、このロボットは、洞窟に入ってバッテリーの前に来たところで動作しなくなり、そのまま時限爆弾が作動してロボットは吹っ飛んでしまった。2号機は、バッテリーの前で「このバッテリーを動かすと上にのった爆弾は爆発しないかどうか」「バッテリーを動かす前に爆弾を移動させないといけないか」「爆弾を動かそうとすると、天井が落ちてきたりしないか」「爆弾に近づくと壁の色が変わったりしないか」などなど、副次的に発生しうるあらゆる事項を考え始めてしまい、無限に思考し続けてしまったのである。これは、副次的に発生しうる事項というのが無限大にあり、それら全てを考慮するには無限大の計算時間を必要とするからである。ただ、副次的に発生する事項といっても、「壁の色がかわったりしないか」などというのは、通常、考慮する必要がない。

そこで、目的を遂行するにあたって無関係な事項は考慮しないように改良した人工知能ロボット3号機R2-D1を開発した。しかし、このロボットは、洞窟に入る前に動作しなくなった。3号機は、洞窟に入る前に、目的と無関係な事項を全て洗い出そうとして、無限に思考し続けてしまったのである。これは、目的と無関係な事項というのも無限大にあるため、それら全てを考慮するには無限大の計算時間を必要とするからである。

このようにR2-D2の実現は難しいのである。

人間にとってこのロボットの思考は素っ頓狂であり、このような思考を展開することはまずない。何故ならば、我々は自然に「問題を解決するために必要なもの」だけを数多く存在する事象の中から瞬時に選択して行動することが出来るからだ。何故そのような能力が人間に備わっておりコンピュータでは簡単に実現できないか?とうことについては話が脱線するので書かないが、この話のミソは論理的な思考だけを突き詰めて行くと「論理的思考の持ち主の代表格」であるコンピュータと同様のフレーム問題に直面するということである。Xという問題を解決するのにYという事象が無関係であることを論理的に証明しなければならないとしたら、Y', Y'', Y'''・・・と永遠に全ての事象についても同様に無関係であることを証明しなければならず、我々の思考はそこで停止してしまうことだろう。

フレーム問題を考察によって得られるひとつの帰結は、皮肉にも「問題の解決策を探るのに必要なアプローチは論理的であってはならない」ということである。つまり、「Xという問題について考えよう!」となったとき、非論理的な思考を導入しなければ議論は一向に進まないのである。とはいえ、そのような非論理的な思考は我々が自然に発揮することが出来る能力だから我々がフレーム問題に直面する心配はない。

常識という暗黙の了解

これまでの話のポイントを(非論理的に)整理すると次のようになる。
  • ディスカッションの目的を見失ってはならない。
  • そもそも完璧な論理というものは幻想なので、そのようなものを追求するのは徒労に終わる。(根拠1:ゲーデルの不完全性定理、根拠2:フレーム問題)
  • ゆえに、論理的な正しさにこだわりすぎるのは良くない。
「それならばそもそも論理的に議論するということ自体が無駄じゃないの?」と思われる方も居るだろう。しかしそのような身も蓋もないことがまかり通ってはどのような議論も不毛なものにならざるを得ないし、このブログを読んで下さっている諸氏の時間を無駄にしてしまうことになるだろう。完璧な論理というものが存在しないと仮定した上で、我々が建設的な議論をする(もしくは単に論理的な思考をする)にはどうすればいいだろうか。

我々が何かについて議論、例えば「AならばCという命題が正しいか」どうかと言うことについて議論するとき、議論に参加しているメンバーは前提条件である「Aが正しい」という命題を無条件で肯定する必要がある。何故ならば、「そもそもAという命題が正しくない」となったら、「AならばC」という命題の正しさを考えるのは無意味だからだ。Aが正しいことを証明することは不可能だが、一般的な問題、例えば「日常生活におけるマナーについて」といったことを議論する場合、その前提となっている暗黙の了解は「常識」に基づいていると考えて差し支えない。つまり、「Aという命題が正しいこと」や、「Xという問題を解決するにはZというアプローチが有効である」というような思考は常識(ないしは前提知識)によってもたらされるわけである。

共通の前提知識が共有されている場合、論理的なアプローチによるディスカッションはとても建設的なものになるだろう。しかし逆に、ある命題についての認識が異なる場合(一方はAが正しいと思っていて、他方はAが正しくないと考えている場合など)は、ディスカッションは悲惨な結果にしかならない。俗に言う「水掛け論」の状態である。とは言え、個々人の常識などというものにはどうしようもない個人差が存在するので、実際のディスカッションではお互いの常識が同じかどうかということについては白黒ハッキリしないのが当然であり、言わば常に「前提がグレーな状態」で議論を交わすことになるといって差し支えない。そのような状態で議論を建設的なものにするには次のようなアプローチを取るのが良いだろう。
  • 相手との共通点を確認する。例:「xxxxxは正しいという認識で合ってますね?」
  • 相手の主張を受け入れる。例:「xxxxxという主張は自分は100%正しいとは思わないが、いったんその前提で話を進めようか。」
  • 議論を通じて共通の認識を構築する。例:「xxxxxという点は合意に至りました。それでは議論をさらに進めましょう。」
要するに、お互いの共通の認識の上にさらに次の共通認識を作り上げるというのが、建設的かつ論理的なコミュニケーションなのである。(同様に、ある命題を前提条件として、さらなる次の命題へと演繹によって発展させるのが論理的思考であると言えよう。)

まとめ

ここでさらに話を強引にまとめると、「やっぱり常識とかバランス感覚って大事なんだね!」ということに集約される。結局常識がなければ論理的なコミュニケーションは成り立たないのだから。最近の日本では常識というものが非常に多様化してきており、これまで島国という特殊な環境で(つまり価値観が非常に似通っているという状況で)過ごしてきた日本人にとっては少々厄介な世の中になってきていると言えるだろう。価値観が多様化すればそれだけ柔軟な思考、別の言い方をすると相手の常識や価値観を認めるというスキルが求められる。つまり謙虚さが必要なのである。

謙虚さを忘れず相手の意見を尊重し、建設的な意見交換を行いたいものである。

おまけ。Windows vs Mac vs Linux

議論を建設的なものにするには共通の認識、つまり互いの常識が重要であることは述べた通りであるが、逆に言うと常識が異なるもの同士が議論をするとロクでもないことになってしまうということが言える。ギークにとって最も代表的な水掛け論はOS論争ではないだろうか。Windows信者、Mac信者、Linux信者でそれぞれ価値観や常識が異なるのだから、お互いが例えば「どのOSの作業効率性が最も優れているか」について議論しても建設的になることはないだろう。

つまり、意気投合する者同士好き勝手喋ってろ!ということである。(あ、コレやっぱり身も蓋もないw)

2009-12-04

サポートエンジニアが経験から語る、論理的文章によるコミュニケーションのススメ

俺はこれまで一貫してIT業界でエンジニアとしてのキャリアを進んできたのだが、これまでのキャリアでもう一つ一貫していることがある。それは、ずっとサポートエンジニアであるということだ。実はサポート職というのはかなり論理的なコミュニケーションを必要とする職種であり、如何に論理的な文章を上手に書くかということが、如何に良い仕事をするか(短い時間で成果=顧客満足度を得られるか)ということに繋がるという側面がある。(もちろん高い技術力が必要なのは言うまでもないが。)サポートエンジニアはメールや報告書という形で日々論理的な文章を書かなければならないので、サポートの経験を重ねることによって論理的にコミュニケーションをする能力というのは徐々に磨かれよう。しかし、論理的にコミュニケーションをするというのは意外と皆出来ているようで出来ていないし、筋が悪いといつまで経っても身につかないこともあり、上手にお客さんを説得することが出来ずにクレームを受けやすい人が居るのも確かだ。

そこで、今日は漢がサポート職を通じて身につけた「論理的な文章の書き方」ということについて、ポイントを紹介しようと思う。

最も大事なことは、ちゃんと質問に回答すること。

何を今更ワケの分からないことを言ってるんだ?そんなの当たり前じゃないか?と思ってしまうかも知れない。しかし、この基本中の基本とも言えることが実は意外と出来てないことが多いのである。実は質問というのは、内容はバリエーションに富んでいるが、質問の形式というのは種類が決まっている。そして、個々の質問の形式に合った回答をしないと、質問に答えたことにはならないのである。如何に有益な情報を書いて相手にメールを送ったとしても、相手の質問に回答していなければ意味がない。それどころか、お客さんは「ちゃんと俺の質問に答えていない」とイライラを募らせてメールをよこす羽目になってしまうのである。

3つしかない「質問」の形式

形式はたったの3つしかないだと?「ハァ?バカにするなよ!」と思われる方はまず落ち着いて続きを読んで欲しい。それは紛れもない事実なのである。「なんだって?質問だったら何でも聴けるんじゃないのか?」という意見もあるしそれは確かに正しいのだが、質問の内容は千差万別でもその形式にはバリエーションはないのである。3つしかないのだから誰だって覚えられるし対策もできる!というわけで、是非これを読んでいるアナタも試してみて欲しい。その3つの形式とは次の通り。

  1. Yes/Noで回答できる質問
  2. 5W1Hの質問
  3. それ以外の質問

それではこれらについて、順を追って説明していこう。

Yes/Noで回答できる質問

最もシンプルかつ多く見受けられるのが、YesかNoで回答出来る質問だ。最もシンプルな例を挙げると「Is this a pen?」というような質問がこのカテゴリに該当する。YesかNoで回答できる質問(以下Yes/No質問)には、YesかNo以外の回答をしてはいけない。そんなの当たり前じゃないかと思うだろうが、これは実は多くの人が無意識のうちに破ってしまう約束事である。どういう事かというと、相手はYesかNoか?と聞いているのについそれ以外の回答をしてしまうということだ。ちょっと卑近な例として、スーパーの生鮮食品売り場で買い物をするときの例を見てみよう。(ちょっとバカ会話だが。。。)

客:このハマチは日本海側でとれたの?
店員:つやがいいでしょう?たくさん餌を食べた証拠です。ひとつどうですか奥さん。
客:そうねえ、ひとついただこうかしら。

この文章を見ておかしいと思わない人はアウトーーーーッ!!である。「だって普通の日常会話じゃこんなのよくあるだろ?」と思われるかも知れない。確かにその通りなのだが、そもそも日常会話自体が論理的ではない。論理的なコミュニケーションをする上で、日常会話の常識は邪魔なのである。この質問では、お客さんは日本海側で取れたのかどうかということを聞いているのだから、論理的に回答しようとするならばYesかNo、つまり「はい」か「いいえ」以外の答えしかあり得ないのである。サポートの仕事では、この形式の質問として次のようなものを多く見かける。

xxxxxxがxxxxxxという動作をするのは仕様ですか?
xxxxxが起きた原因はxxxxxですか?
xxxxxでxxxxxという操作をすることは可能ですか?

因みに、今話題の仕分け人が放った質問「1位じゃなきゃダメなんですか?」というのもYes/No質問である。

この形式の質問では、まずYesかNoではっきりと回答すること!言い回しは何でもいい(例:おっしゃる通りですetc)のだが、まずはYesかNoの意思表示が重要なのである。

ただし、Yes/No質問には一つ注意しなければいけない罠がある。それは、例えば答えがYesだったとき、「はい」だけ回答しただけではいけないということである。

例えば、

> xxxxxが起きた原因はxxxxxですか?
はい、そうです。

というようなメールを送ったとしたら、相手は「なんて不親切なサポートなんだろう」と思ってしまう。何故ならば、相手は暗黙的にさらにその回答に対してコメントを求めていることが多いからである。上記の「xxxxxが起きた原因はxxxxxですか?」というような質問では、相手はその裏付けとなる根拠を説明して貰いたいと思っている場合がほとんどであり、その暗黙的な質問に対しても回答しなければ相手を満足させることは出来ない。このように、額面の裏に隠された質問を察することが、Yes/No質問では大事なのである。

もう一つ注意点としては、相手の質問に対してYesかNoで答えることが不可能な場合がある。例えば、

MySQLはPostgreSQLよりも高速ですか?

と聞かれてもYesかNoでは答えられないだろう。このような場合には、「一概に言えない」とか「場合による」といった回答が相応しい。ただし、この場合ももちろんその根拠をコメントすることを忘れてはならない。

5W1Hの質問

5W1Hとはつまり、Who(誰が) What(何を) When(いつ) Where(どこで) Why(どうして)How(どのように)したのか、という形式の質問である。勘の良い方なら、5W1Hに対してどのように回答すれば論理的な回答になるかということがおわかりだろう。そう、聞かれたことに回答すれば良いのである。5W1Hを聞かれたら、まずはその対象を答えるべきなのだ。次は夫婦の会話だが、夫はちゃんと妻の質問に答えていない。
妻:今日は何時に帰ってくるの?
夫:ちょっと取引先の人と会ってくるよ。

この場合、夫は帰宅時刻のおおよその見積もり(When)を答えなければならないはずであるが、取引先の人と会うという事柄(What)について述べているのでこれは論理的ではない。「取引先の人と会うから遅くなるということを察しろ」という意見があるかも知れない。それは確かに日常会話ではそれは通じる場合が多いのだが、論理的なコミュニケーションではそのようなやり取りは相応しくないということを理解して貰いたいのである。

サポートで見かける5W1H質問には、例えば次のようなものがある。
xxxxという操作をするためのコマンドは何ですか?(What)
xxxxがクラッシュした原因は何ですか?(Why)
このエラーはいつの時点から発生していたのでしょうか?(When)
この状態から復旧するにはどのようにすれば良いのでしょうか?(How)

ちなみに、WhoやWhereを聞かれることはあまりない。例えば「誰が作業をしたのか?」などという質問をされても、サポートサイドでは回答出来ない(ということをお客さんも当然知っている)からである。

5W1Hの場合は、Yes/No質問のように暗黙的な隠れた質問があることは少ない。質問者はダイレクトに自分の疑問を聞いている場合が多く、聞かれたことを全力で説明すれば良いというわけである。

それ以外の質問

3つのパターンの中で最も答えるのが難しいのが、Yes/Noにも5W1Hにも当てはまらない質問である。漠然としたことについて意見を求めるようなケースである。この手の質問としては、例えば次のようなものがある。

MySQL Clusterについて教えて下さい。
バイナリログの仕組みを教えて下さい。
MySQLをバックアップするにはどうすればいいでしょうか。
データベースのパフォーマンスチューニングはどのようにすれば良いのでしょうか。

このような質問をしてくる背景として、お客さんが何かを知りたいのだがどこから聞いて良いのか掴み切れていないという状況が多い。このような質問をされると、

オーケー。じゃあまず何から話そうか。

ということになってしまう。何を回答するかは回答者次第、言ってみれば自由なのだ。自由だから何でも書いて良いというわけではない。質問者を満足させる回答でなければならないので、正直言ってこれが一番回答に困る質問の形式であると言えよう。だからこそ腕の見せ所であると言える。

ここで注意しなければいけないのは、「マニュアル嫁」という味も糞もミソもカンガルーもない反応をしてしまうことである。確かにそれは真理である場合もあるのだが、そのような回答は英語では「RTFM=Read The F@cking Manual」として揶揄されるよくない対応である。サポートエンジニアたるもの、努々RTFM的な回答をするなかれ。なんたってお金を頂いているわけだから。

ではRTFMの代わりにどのような回答をすれば良いのだろうか。このような質問をしてくる質問者は、たいてい質問している内容についてあまり詳しくない場合が多い。そんな質問者は質問している対象を1〜100まで全部知りたいわけでなく、その概要を知りたがっていると見なすべきである。従って、この手の「漠然とした質問」に対しては一般的な見解をすっきり短くまとめるのが良い。つまり、ここでは「要約して説明する」というスキルが求められるのである。要約した回答を送った上で、質問者がさらに詳しく知りたいと思ったならばさらに質問が送られてくることになるが、追加質問についてもこれまでに紹介した3パターンに当てはめあらた回答すれば良いだろう。

ただ、人に何かを要約して説明するというのは、仕事には欠かせないにも関わらず非常に難しい高度なスキルである。しかもそのスキルの追求には終わりがなく、如何に分かり易い文章を書くかということは文章を書く者全てにとっての永遠のテーマであると言えるだろう。自由なフォーマットで相手に何かを要領よく説明する場合、文章全体の構成をどのようにするか、説明する内容をどこに絞るかということが重要だとよく言われる。つまり、相手が知りたがっている情報を効果的に提供することが大事なのである。

サポートの場合、相手の立場を考えた上で必要な情報を提供するには次のポイントが大事である。

一、ユーザーの運用を理解する。

この手の「一般的な質問」をする場合、質問者は間違いなくその機能が質問者の環境でどのように利用出来るかどうかということを検討していると言って良い。従って、運用者の立場、即ちユーザーの利用シーンを考えることが重要なのである。例えばMySQL Clusterの場合、高可用性や運用方法などが、質問者の目的に合っているかどうかということを判断したいわけだ。

一、技術(製品)についてよく理解する。

回答する対象の技術や製品について詳しく研究しておくことがとても重要である。つまり、ネタ帳の中身が詰まっていないと良いネタが出てこないということである。対象の製品について、日々研究することもやはり大事なのである。

一、よく聞かれる質問についてはテンプレートとしてまとめておく。

毎回同じ文章を書いても良いが、毎回同じ回答になるような質問についてはテンプレート化しておくと便利である。テンプレートを作っておくのは効率が良いし、何よりそのテンプレートを随時更新することによって回答の品質が高まっていくことになるからだ。手間はRTFM的な回答をする場合と比べてそれほど増えないにも関わらず、質問者に対する印象は180℃違うことになるので非常にお得である。

ここではカスタマーサポートにおいて「漠然とした質問」に回答する際に役立つポイントについて紹介したが、この形式の質問に対する回答の質を高めるには、とにかく書いて書いて練習するのが最も重要であるということを付け加えておく。

まとめ

というわけで、質問には3つの形式があって、それぞれの形式に合った方法で回答しなければいけない。その3つの形式とは、
  • Yes/No質問
  • 5W1Hの質問
  • それ以外の(漠然とした)質問
である。それぞれ聞かれたことに対して回答する際の注意点については上で述べた通りである。くれぐれもRTFM的な回答をしてはならない。この法則に当てはめて確認すれば、書いた文章が論理的であるかどうかを判断することが出来るだろう。論理的なコミュニケーションを行うのは易しいことではないが、文章の論理性を高めて建設的な意見交換をする一助になれば幸いである。

2009-12-02

特定のデータベースだけをmysqldumpで作成したダンプファイルから抜き出すawkスクリプト

タイトルのまんまのプチトリビアを紹介しようと思う。mysqlの--one-databaseオプションを使えば「mysqldumpで--all-databasesとか--databasesオプションを使って作成したダンプファイルに含まれる複数のデータベースから、一つのデータベースだけを選択してリストアする」という操作ができるけど、毎回ダンプファイル全体を読み込むのは無駄じゃないか?と思われることもあるだろう。だったら事前にダンプファイルを分けちゃいたい!と考えるのが人情というもの。そんなときはawkコマンドを使うといい。
#!/usr/bin/awk -f

BEGIN {
  dump_current_db = 0;
  num_db = split(databases, db_arr, ",")
  for (i = 1; i <= num_db; i++) {
    db_arr[i] = "`" db_arr[i] "`";
  }
}

/^\-\-/ {
  print $0;
  if ($2 == "Current" && $3 == "Database:") {
    dump_current_db = 0;
    for (i = 1; i <= num_db; i++) {
      if ($4 == db_arr[i]) {
        dump_current_db = 1;
        break;
      }
    }
  }
}

/^\/\*.+\*\/;/ { print $0 }

/^$/ { print $0 }

/^[^\-]/ { if (dump_current_db == 1) print $0 }
このawkスクリプトを例えばcut-database.awkとかに保存して、
shell> ./cut-database -v databases=db1,db2,db3... < dump.sql > sub_dump.sql
てな具合にコマンドを起動すれば、目的のデータベースだけを含んだダンプファイルがいっちょあがり。 そもそもmysqldumpコマンドでダンプするときにファイルを分ければ?なんて考える人も居るかも知れないけど、それは出来ない相談だったりする。ロールフォワードリカバリとかを考えてバイナリログと同期をとっておかないといけなかったりするし、そもそもデータベースが複数あるときにはデータベース間でデータが同期していないといけない。ところがデータベースを個別にダンプするとロールフォワードリカバリが出来ないどころか、データが使い物にならないことになってしまう。よって--all-databasesとか--databasesの利用は必須なのである。 そこでもう一つ紹介するのが、mysqldumpコマンドの出力をそのまま別々のファイルに保存するawkスクリプト。
#!/usr/bin/awk -f

function is_new_db(db_name) {
  for (i = 1; i <= num_db; i++) {
    if (db_name == db[i]) {
      return 0;
    }
  }
  return 1;
}

BEGIN {
  num_db = 0
  num_prelines = 0
  num_postlines = 0
  current_file = "/dev/null"
}

/^\-\-/ {
  if ($2 == "Current" && $3 == "Database:") {
    close(current_file);
    db_name = $4
    gsub("`", "", db_name);
    current_file = db_name ".sql";
    if (is_new_db(db_name)) {
      db[++num_db] = db_name;
      print "--\n" $0 "\n--\n" > current_file;
      for (i = 1; i <= num_prelines; i++)
        print prelines[i] >> current_file;
    }
  } else if (num_db == 0) {
    num_prelines++;
    prelines[num_prelines] = $0;
  } else if ($2 == "Dump" && $3 == "completed") {
    num_postlines++;
    postlines[num_postlines] = "";
    num_postlines++;
    postlines[num_postlines] = $0;
  } else {
    print $0 >> current_file
  }
  next;
}

/^\/\*.+\*\/;/ {
  if (match($0, "character|collation")) {
    print $0 >> current_file;
  } else if (match($0, "SET")) {
    if (num_db == 0) {
      if (match(prelines[num_prelines], "^\-\-")) {
        num_prelines++;
        prelines[num_prelines] = "";
      }
      num_prelines++;
      prelines[num_prelines] = $0;
    } else {
      num_postlines++;
      postlines[num_postlines] = $0;
    }
  } else {
    print $0 >> current_file;
  }
  next;
}

{ print $0 >> current_file }

END {
  for (i = 1; i <= num_db; i++) {
    current_file = db[i] ".sql";
    print "" >> current_file
    for (j = 1; j <= num_postlines; j++) {
      print postlines[j] >> current_file;
    }
  }
}
このスクリプトを例えばseparate-dump.awkというファイルに保存して実行権限を与えてやれば、
shell> mysqldump -A --single-transaction --master-data=2 --flush-logs | ./separate-dump.awk
という具合にこのコマンドを使うことができる。そうするとカレントディレクトリに「データベース名.sql」というファイルにダンプが分けられて保存されるという寸法。DB数が多い場合は"Too many open files”エラーが出てしまうので注意すること。(色々直しました。) もちろん既存のダンプファイルを分けることも可能。
shell> ./separate-dump.awk < dump.sql

なお、このスクリプトの利用は自己責任でお願いします。ライセンスはGPLv3で。何か不具合等があれば直して使って下さい。