<?xml version="1.0" encoding="utf-8"?>

<rdf:RDF
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
  xmlns:admin="http://webns.net/mvcb/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:cc="http://web.resource.org/cc/"
  xmlns="http://purl.org/rss/1.0/">

<channel rdf:about="http://developer.cybozu.co.jp/kazuho/">
<title>Kazuho@Cybozu Labs</title>
<link>http://developer.cybozu.co.jp/kazuho/</link>
<description>Weblog of Kazuho Oku (奥 一穂) in Japanese and in English</description>
<dc:language>ja-JP</dc:language>
<dc:creator></dc:creator>
<dc:date>2010-02-24T09:34:36+09:00</dc:date>
<admin:generatorAgent rdf:resource="http://www.typepad.com/" />


<items>
<rdf:Seq><rdf:li rdf:resource="http://developer.cybozu.co.jp/kazuho/2010/02/tco-hbstudy8-5f.html" />
<rdf:li rdf:resource="http://developer.cybozu.co.jp/kazuho/2010/01/thanks-to-a-use.html" />
<rdf:li rdf:resource="http://developer.cybozu.co.jp/kazuho/2010/01/building-a-high.html" />
<rdf:li rdf:resource="http://developer.cybozu.co.jp/kazuho/2010/01/cronlog-52f2.html" />
<rdf:li rdf:resource="http://developer.cybozu.co.jp/kazuho/2010/01/blockdiff-linux.html" />
</rdf:Seq>
</items>

</channel>

<item rdf:about="http://developer.cybozu.co.jp/kazuho/2010/02/tco-hbstudy8-5f.html">
<title>既製品の管理ツールを使わないことでウェブサービスの TCO を下げる話について hbstudy#8 で話してきた件</title>
<link>http://developer.cybozu.co.jp/kazuho/2010/02/tco-hbstudy8-5f.html</link>
<description>　昨日、hbstudy#8 で話をする機会をいただくことができたので、Nagios や Amanda といった既製品の管理ツールやバックアップツールを使わずに内製したことで「パストラック」の運用コスト...</description>
<content:encoded>&lt;p&gt;　昨日、&lt;a href=&quot;http://heartbeats.jp/hbstudy/2010/02/hbstudy8.html&quot;&gt;hbstudy#8&lt;/a&gt; で話をする機会をいただくことができたので、Nagios や Amanda といった既製品の管理ツールやバックアップツールを使わずに内製したことで「&lt;a href=&quot;http://pathtraq.com/&quot;&gt;パストラック&lt;/a&gt;」の運用コストを下げた、という話をしてきました。&lt;/p&gt;

&lt;p&gt;　もちろん、「既製品を使わない」というのもひとつの手段にすぎませんから、それを無闇にお勧めするつもりはありません。ただ、小回りの効くツールを組み合わせる手法にも十分な競争力があるという点、あるいはその事例として参考になれば幸いです。&lt;/p&gt;

&lt;p&gt;　スライドはこちら。hbstudy 運営の皆様、話を聞いてくださった皆様、ありがとうございました。&lt;/p&gt;

&lt;div id=&quot;__ss_3261013&quot; style=&quot;width: 425px; text-align: left;&quot;&gt;&lt;a title=&quot;Infrastructure of Pathtraq&quot; href=&quot;http://www.slideshare.net/kazuho/infrastructure-of-pathtraq-3261013&quot; style=&quot;font: 14px Helvetica,Arial,Sans-serif; display: block; margin: 12px 0pt 3px; text-decoration: underline;&quot;&gt;Infrastructure of Pathtraq&lt;/a&gt;&lt;object height=&quot;355&quot; width=&quot;425&quot; style=&quot;margin: 0px;&quot;&gt;&lt;param value=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=20090223hbstudy-pathtraq-infra-100223181053-phpapp01&amp;amp;stripped_title=infrastructure-of-pathtraq-3261013&quot; name=&quot;movie&quot; /&gt;&lt;param value=&quot;true&quot; name=&quot;allowFullScreen&quot; /&gt;&lt;param value=&quot;always&quot; name=&quot;allowScriptAccess&quot; /&gt;&lt;embed height=&quot;355&quot; width=&quot;425&quot; allowfullscreen=&quot;true&quot; allowscriptaccess=&quot;always&quot; type=&quot;application/x-shockwave-flash&quot; src=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=20090223hbstudy-pathtraq-infra-100223181053-phpapp01&amp;amp;stripped_title=infrastructure-of-pathtraq-3261013&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style=&quot;font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;&quot;&gt;View more &lt;a href=&quot;http://www.slideshare.net/&quot; style=&quot;text-decoration: underline;&quot;&gt;presentations&lt;/a&gt; from &lt;a href=&quot;http://www.slideshare.net/kazuho&quot; style=&quot;text-decoration: underline;&quot;&gt;kazuho&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;</content:encoded>


<dc:subject>Pathtraq</dc:subject>
<dc:subject>Perl</dc:subject>
<dc:subject>管理・運用</dc:subject>

<dc:creator>Oku Kazuho</dc:creator>
<dc:date>2010-02-24T09:34:36+09:00</dc:date>
</item>
<item rdf:about="http://developer.cybozu.co.jp/kazuho/2010/01/thanks-to-a-use.html">
<title>Q4M 0.9.2 prerelease avaiable fixing data corruption on 32bit systems</title>
<link>http://developer.cybozu.co.jp/kazuho/2010/01/thanks-to-a-use.html</link>
<description>Thanks to a user of Q4M, I have found a bug that would likely lead to data corruption on 32bit versions of Q4M. 64bit versions are unaffected. Q4M by default uses mmap(2) to read from data files. On 32bit systems, it tries to map max. 1GB per each table into memory using mmap. When mmap fails to map memory due to low memory, Q4M falls back to file I/O to read the data. However there was a bug in handling the response from mmap, that led to reading corrupt data from database files when mmap(2) failed after the size of...</description>
<content:encoded>&lt;p&gt;Thanks to a user of &lt;a href=&quot;http://q4m.31tools.com/&quot;&gt;Q4M&lt;/a&gt;, I have found a bug that would likely lead to data corruption on 32bit versions of Q4M.&amp;nbsp; 64bit versions are unaffected.&lt;/p&gt;

&lt;p&gt;Q4M by default uses mmap(2) to read from data files.&amp;nbsp; On 32bit systems, it tries to map max. 1GB per each table into memory using mmap.&amp;nbsp; When mmap fails to map memory due to low memory, Q4M falls back to file I/O to read the data.&lt;/p&gt;

&lt;p&gt;However there was a bug in handling the response from mmap, that led to reading corrupt data from database files when mmap(2) failed after the size of the underlying file was grown / shrunk by Q4M.&amp;nbsp; And since Q4M writes back the corrupt data into the database file when rows are being consumed, the bug will likely destroy the database files.&lt;/p&gt;

&lt;p&gt;I have fixed the bug and have uploaded Q4M 0.9.2, into the prerelease directory at &lt;a href=&quot;http://q4m.31tools.com/dist/pre/&quot;&gt;q4m.31tools.com/dist/pre&lt;/a&gt;.&amp;nbsp; Source tarball and prebuilt binaries for MySQL 5.1.42 for 32bit linux are available.&lt;/p&gt;

&lt;p&gt;If you are using 32bit versions of Q4M, I highly recommend either to update to 0.9.2 or switch to 64bit versions if possible.&lt;/p&gt;

&lt;p&gt;BTW in 0.9.2 release, I also changed the maximum mmap size per table from 1GB to 256MB, to lower the possiblity of low memory.&amp;nbsp; However this countermeasure might not be sufficient in some cases, i.e. databases having many Q4M tables or if other storage engines also used a lot of memory.&amp;nbsp; I am considering of just disabling the use of mmap(2) on 32bit systems in future releases.&amp;nbsp; If you have any comments on this, please let me know.&lt;/p&gt;</content:encoded>


<dc:subject>in English</dc:subject>
<dc:subject>MySQL</dc:subject>

<dc:creator>Oku Kazuho</dc:creator>
<dc:date>2010-01-22T01:26:00+09:00</dc:date>
</item>
<item rdf:about="http://developer.cybozu.co.jp/kazuho/2010/01/building-a-high.html">
<title>Building a highly configurable, easy-to-maintain backup solution for LVM-based VMs and MySQL databases</title>
<link>http://developer.cybozu.co.jp/kazuho/2010/01/building-a-high.html</link>
<description>Motives and the Features For the servers running in our new network, I was in need for a highly configurable, but easy-to-use backup solution that can take online backups of VMs and MySQL databases running multiple storage engines. Since my colleagues are all researchers or programmers but there are no dedicated engineers for managing our system, I decided to write a set of command line scripts to accomplish the task instead of using an existing, highly-configurable but time-taking-to-learn backup solutions, like Amanda. And what I have come up with now is a backup solution with following characteristics, let me introduce...</description>
<content:encoded>&lt;p&gt;&lt;strong&gt;Motives and the Features&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For the servers running in our new network, I was in need for a highly configurable, but easy-to-use backup solution that can take online backups of VMs and MySQL databases running multiple storage engines.&lt;/p&gt;

&lt;p&gt;Since my colleagues are all researchers or programmers but there are no dedicated engineers for managing our system, I decided to write a set of command line scripts to accomplish the task instead of using an existing, highly-configurable but time-taking-to-learn backup solutions, like &lt;a href=&quot;http://amanda.zmanda.com/&quot;&gt;Amanda&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And what I have come up with now is a backup solution with following characteristics, let me introduce them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a central backup server able to take backup of other servers over SSH using public-key authentication&lt;/li&gt;
&lt;li&gt;no need to install backup agents into each server&lt;/li&gt;
&lt;li&gt;LVM snapshot-based online, incremental backups (capable of taking online backups of LVM-based VMs)&lt;/li&gt;
&lt;li&gt;taking online backups of MySQL databases running mulitple storage engines with sophisticated lock control&lt;/li&gt;
&lt;li&gt;no configuration files, only use crontab and shell-scripts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The solution consists of two tools, blockdiff (&lt;a href=&quot;http://github.com/kazuho/blockdiff&quot;&gt;kazuho&#39;s blockdiff at master - GitHub&lt;/a&gt;), and cronlog script of kaztools (&lt;a href=&quot;http://github.com/kazuho/kaztools&quot;&gt;kazuho&#39;s kaztools at master - GitHub&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blockdiff&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Blockdiff is a set of scripts for taking block-based diffs of files or volumes on a local machine or on remote machines over the network using SSH.&amp;nbsp; The script below takes online backup of three LVM volumes from three servers.&amp;nbsp; In the form below, a full backup will be taken once a month, and incremetal backups will be taken during every month.&lt;/p&gt;

&lt;div style=&quot;text-align: center; font-weight: bold;&quot;&gt;backup.sh&lt;/div&gt;
&lt;pre style=&quot;border: 1px solid gray; margin: 0.2em 0pt 1em; padding: 0.5em; background: rgb(238, 238, 238) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot;&gt;#! /bin/bash&lt;br /&gt;&lt;br /&gt;export YEARMONTH=`date &#39;+%Y%m&#39;`&lt;br /&gt;&lt;br /&gt;# backup a LVM volume (using snapshot) at /dev/pv/lv on srv00&lt;br /&gt;blockdiff_backup /var/backup/srv00-pv-lv-$YEARMONTH ssh_lvm_dump --gzip \&lt;br /&gt;&amp;nbsp; root@srv00 /dev/pv/lv \&lt;br /&gt;&amp;nbsp; || exit $?&lt;br /&gt;&lt;br /&gt;# backup another LVM volume on an another server&lt;br /&gt;blockdiff_backup /var/backup/srv01-pv-lv-$YEARMONTH ssh_lvm_dump --gzip \&lt;br /&gt;&amp;nbsp; root@srv01 /dev/pv/lv \&lt;br /&gt;&amp;nbsp; || exit $?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# backup a MySQL database stored on volume /dev/pv/lv on server db00 &lt;br /&gt;BLOCKSIZE=16384 \&lt;br /&gt;&amp;nbsp; LVCREATE_PREFIX=&#39;mysqllock --host=db00 --user=root --password=XXXX&#39; \&lt;br /&gt;&amp;nbsp; blockdiff_backup /var/backup/db00-pv-lv-$YEARMONTH ssh_lvm_dump --gzip \&lt;br /&gt;&amp;nbsp; root@db00 /dev/pv/lv \&lt;br /&gt;&amp;nbsp; || exit $?&lt;/pre&gt;


&lt;p&gt;The backup command of the last volume uses &lt;em&gt;mysqllock&lt;/em&gt; command included in blockdiff to keep &amp;quot;FLUSH TABLES WITH WRITE LOCK&amp;quot; running while taking a snapshot of the LVM volume on which the database files exist.&amp;nbsp; It is also possible to implement other kinds of locks so as not to issue the &amp;quot;FLUSH TABLES WITH WRITE LOCK&amp;quot; while long-running queries are in execution.&amp;nbsp; Since the flush statement blocks other queries until all of the already running queries complete, issuing the flush query when long-running queries exist will lead to the database not responding to other queries for a certain amount of time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Crontab and the cronlog script&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The backup script is invoked by cron via cronlog, a script that logs the output of the executed task, as well as controlling the output passed to cron so that an alert mail will be sent when the backup script fails.&amp;nbsp; It uses setlock command of &lt;a href=&quot;http://cr.yp.to/daemontools.html&quot;&gt;daemontools&lt;/a&gt; for holding an exclusive lock while running the backup script (and to alert the administrator on when failing to acquire the lock).&lt;/p&gt;

&lt;div style=&quot;text-align: center; font-weight: bold;&quot;&gt;Crontab script&lt;/div&gt;
&lt;pre style=&quot;border: 1px solid gray; margin: 0.2em 0pt 1em; padding: 0.5em; background: rgb(238, 238, 238) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot;&gt;MAILTO=admin@example.com&lt;br /&gt;5 3 * * * cd /var/backup &amp;amp;&amp;amp; exec setlock -nX /tmp/backup.lock cronlog -l /var/backup/backup.log -t -- ./backup.sh 2&amp;gt;&amp;amp;1&lt;/pre&gt;


&lt;p&gt;This is all that needs to be set up to backup LVM volumes including MySQL databases.&amp;nbsp; Output of the log will be like the following.&lt;/p&gt;

&lt;div style=&quot;text-align: center; font-weight: bold;&quot;&gt;backup.log&lt;/div&gt;
&lt;pre style=&quot;border: 1px solid gray; margin: 0.2em 0pt 1em; padding: 0.5em; background: rgb(238, 238, 238) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot;&gt;------------------------------------------------------------------------------&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:05:02 2010] backup-srv starting: ./backup.sh&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:05:02 2010] creating snapshot...&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:05:07 2010]&amp;nbsp; &amp;nbsp;Logical volume &amp;quot;lvm_dump&amp;quot; created&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:05:07 2010] running: ssh_blockdiff_dump --gzip &amp;quot;root@srv00&amp;quot; &amp;quot;/dev/pv/lv&amp;quot;...&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:19:22 2010] removing snapshot /dev/pv/lvm_dump...&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:19:23 2010]&amp;nbsp; &amp;nbsp;Logical volume &amp;quot;lvm_dump&amp;quot; successfully removed&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:19:23 2010] backup completed successfully&lt;br /&gt;(snip)&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:35:56 2010] creating snapshot...&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:35:56 2010] issuing lock statement: FLUSH TABLES WITH READ LOCK&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:36:00 2010]&amp;nbsp; &amp;nbsp;Logical volume &amp;quot;lvm_dump&amp;quot; created&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:36:00 2010] issuing unlock statement: UNLOCK TABLES&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:36:00 2010] running: bin/ssh_blockdiff_dump --gzip &amp;quot;root@db00&amp;quot; &amp;quot;/dev/pv/lv&amp;quot;...&lt;br /&gt;[Sat Jan&amp;nbsp; 9 04:18:44 2010] removing snapshot /dev/pv/lvm_dump...&lt;br /&gt;[Sat Jan&amp;nbsp; 9 04:18:46 2010]&amp;nbsp; &amp;nbsp;Logical volume &amp;quot;lvm_dump&amp;quot; successfully removed&lt;br /&gt;[Sat Jan&amp;nbsp; 9 04:18:46 2010] backup completed successfully&lt;br /&gt;[Sat Jan&amp;nbsp; 9 04:18:46 2010] command exited with code:0&lt;/pre&gt;

&lt;p&gt;The files in the backup directory will be like below.&amp;nbsp; The .gz files contain the backup data, and .md5 files contain per-block checksums used for taking incremental or differential backups.&lt;/p&gt;

&lt;div style=&quot;text-align: center; font-weight: bold;&quot;&gt;The backup files&lt;/div&gt;
&lt;pre style=&quot;border: 1px solid gray; margin: 0.2em 0pt 1em; padding: 0.5em; background: rgb(238, 238, 238) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot;&gt;% ls -l db00-pv-lv-201001*&lt;br /&gt;-rw-r--r-- 1 backup backup 50289166539 2010-01-01 05:35 db00-pv-lv-201001.1.gz&lt;br /&gt;-rw-r--r-- 1 backup backup&amp;nbsp; &amp;nbsp;131072004 2010-01-01 05:35 db00-pv-lv-201001.1.md5&lt;br /&gt;-rw-r--r-- 1 backup backup 10914423057 2010-01-02 04:32 db00-pv-lv-201001.2.gz&lt;br /&gt;-rw-r--r-- 1 backup backup&amp;nbsp; &amp;nbsp;131072004 2010-01-02 04:32 db00-pv-lv-201001.2.md5&lt;br /&gt;-rw-r--r-- 1 backup backup 13648250036 2010-01-03 04:33 db00-pv-lv-201001.3.gz&lt;br /&gt;-rw-r--r-- 1 backup backup&amp;nbsp; &amp;nbsp;131072004 2010-01-03 04:34 db00-pv-lv-201001.3.md5&lt;br /&gt;(snip)&lt;br /&gt;-rw-r--r-- 1 backup backup&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; 3 2010-01-18 04:34 db00-pv-lv-201001.ver&lt;/pre&gt;

&lt;p&gt;For more information, please read the source code and the accompanying documentation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;

&lt;/p&gt;

&lt;p&gt;As can be seen, this is a powerful backup solution that can be built up with minimum setup. It will work well if you work in a small number of experienced engineers, while it might not be suitable for large-scale deployments with many admins.&amp;nbsp; If you are interested, please give it a try.&amp;nbsp; I am looking forward to your ideas and / or suggestions.&lt;/p&gt;

&lt;p&gt;PS. The blockdiff_merge command can be used to restore the backups.&lt;/p&gt;</content:encoded>


<dc:subject>in English</dc:subject>
<dc:subject>MySQL</dc:subject>

<dc:creator>Oku Kazuho</dc:creator>
<dc:date>2010-01-20T18:54:28+09:00</dc:date>
</item>
<item rdf:about="http://developer.cybozu.co.jp/kazuho/2010/01/cronlog-52f2.html">
<title>監視とは継続的なテストである、という話 (もしくは cronlog とテストスクリプトを組み合わせた監視手法について)</title>
<link>http://developer.cybozu.co.jp/kazuho/2010/01/cronlog-52f2.html</link>
<description>　結論から先に。cronlog を使えば、アプリケーションのテストコードと全く同じ形式で、監視用のスクリプトを書くことができます。プログラマが監視ツールの記法を覚える必要はありません。これは、プログラ...</description>
<content:encoded>&lt;p&gt;　結論から先に。cronlog を使えば、アプリケーションのテストコードと全く同じ形式で、監視用のスクリプトを書くことができます。プログラマが監視ツールの記法を覚える必要はありません。これは、プログラマが運用も行うケースでは特に有効な手法だと思います。&lt;/p&gt;

&lt;p&gt;　先週公開した &lt;a href=&quot;http://developer.cybozu.co.jp/kazuho/2010/01/crontab-f131.html&quot;&gt;Kazuho@Cybozu Labs: crontab を使って効率的にサービス監視する方法&lt;/a&gt; というエントリで、crontab と拙作の cronlog を用いてサービス監視を書く手法を紹介しました。しかし、挙げた例はいずれも ping や http のテストといった外形監視の手法です。RDBMS とウェブアプリケーションのみから構成されるサービスならそれだけで十分でしょう。&lt;/p&gt;

&lt;p&gt;　しかし、外形監視だけでは、メッセージキューのような非同期処理の遅延を観測することはできません。また、http のログを監視して、エラーレスポンスや平均応答時間の監視も行うことが望ましいです。それらの処理をどう書くか。&lt;/p&gt;

&lt;p&gt;　自分は、監視とは継続的なテストである、という観点から、キューの処理遅延等の監視を、アプリケーションのテストスートの一部として書いています。具体的には、以下のような感じ (一部改変)。テストはアプリケーションと設定情報を共有しているので、監視ソフトウェアに様々な設定値を入力する必要もありません。&lt;/p&gt;

&lt;pre style=&quot;border: 1px solid gray; margin: 1em 0pt; padding: 0.5em; background: rgb(238, 238, 238) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot;&gt;use strict;&lt;br /&gt;use warnings;&lt;br /&gt;&lt;br /&gt;use Test::More;&lt;br /&gt;use Pathtraq;&lt;br /&gt;&lt;br /&gt;my $app = Pathtraq-&amp;gt;new;&lt;br /&gt;&lt;br /&gt;cmp_ok&lt;br /&gt;&amp;nbsp; &amp;nbsp; do {&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; my $row = $app-&amp;gt;dbh-&amp;gt;selectrow_arrayref(&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&#39;select XXXX&#39;, # Q4M 使ってない昔のキュー監視&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; ) or die $app-&amp;gt;dbh-&amp;gt;errstr;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; $row-&amp;gt;[0];&lt;br /&gt;&amp;nbsp; &amp;nbsp; },&lt;br /&gt;&amp;nbsp; &amp;nbsp; &#39;&amp;lt;&#39;,&lt;br /&gt;&amp;nbsp; &amp;nbsp; 1000,&lt;br /&gt;&amp;nbsp; &amp;nbsp; &#39;delay of updater&#39;;&lt;br /&gt;&lt;br /&gt;for my $tbl (qw(analyze_page set_page_info analyze_keyword)) {&lt;br /&gt;&amp;nbsp; &amp;nbsp; cmp_ok&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; do {&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;my $row = $app-&amp;gt;dbh_queue-&amp;gt;selectrow_arrayref(&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;quot;select count(*) from $tbl&amp;quot;,&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;) or die $app-&amp;gt;dbh_queue-&amp;gt;errstr;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;$row-&amp;gt;[0];&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; },&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &#39;&amp;lt;&#39;,&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; 1000,&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;quot;delay of $tbl&amp;quot;,&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;done_testing;&lt;/pre&gt;

&lt;p&gt;　あとは、これらのテストコードを、crontab 上で cronlog を介してテストの実行ツール (perl なら prove) に食わせるだけ。&lt;/p&gt;

&lt;pre style=&quot;border: 1px solid gray; margin: 1em 0pt; padding: 0.5em; background: rgb(238, 238, 238) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot;&gt;*/5 * * * * cd /var/webapp &amp;amp;&amp;amp; exec setlock -nX /tmp/monitor.lock cronlog -- prove -v monitor.t/*.t 2&amp;gt;&amp;amp;1&lt;/pre&gt;

&lt;p&gt;　これで、監視対象項目 (＝テスト項目) になんらかの問題が見つかった場合には、以下のような感じのメールが届くようになります。&lt;/p&gt;

&lt;pre style=&quot;border: 1px solid gray; margin: 1em 0pt; padding: 0.5em; background: rgb(238, 238, 238) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot;&gt;Subject: Cron &amp;lt;user@host&amp;gt; cd /var/webapp &amp;amp;&amp;amp; exec setlock -nX /tmp/monitor.lock cronlog -- prove -v monitor.t/*.t 2&amp;gt;&amp;amp;1&lt;br /&gt;&lt;br /&gt;host.example.com starting: prove -v monitor.t/queue.t&lt;br /&gt;&lt;br /&gt;#&amp;nbsp; &amp;nbsp;Failed test &#39;delay of analyze_page&#39;&lt;br /&gt;#&amp;nbsp; &amp;nbsp;at monitor.t/queue.t line 23.&lt;br /&gt;#&amp;nbsp; &amp;nbsp;&amp;nbsp; &#39;1396&#39;&lt;br /&gt;#&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;&lt;br /&gt;#&amp;nbsp; &amp;nbsp;&amp;nbsp; &#39;1000&#39;&lt;br /&gt;# Looks like you failed 1 test of 4.&lt;br /&gt;monitor.t/queue.t ..&lt;br /&gt;ok 1 - delay of updater&lt;br /&gt;not ok 2 - delay of analyze_page&lt;br /&gt;ok 3 - delay of set_page_info&lt;br /&gt;ok 4 - delay of analyze_keyword&lt;br /&gt;1..4&lt;br /&gt;Dubious, test returned 1 (wstat 256, 0x100)&lt;br /&gt;Failed 1/4 subtests&lt;br /&gt;&lt;br /&gt;Test Summary Report&lt;br /&gt;-------------------&lt;br /&gt;monitor.t/queue.t (Wstat: 256 Tests: 4 Failed: 1)&lt;br /&gt; Failed test:&amp;nbsp; 2&lt;br /&gt; Non-zero exit status: 1&lt;br /&gt;Files=1, Tests=4,&amp;nbsp; 0 wallclock secs ( 0.02 usr&amp;nbsp; 0.00 sys +&amp;nbsp; 0.40 cusr&amp;nbsp; 0.08 csys =&amp;nbsp; 0.50 CPU)&lt;br /&gt;Result: FAIL&lt;br /&gt;command exited with code:1&lt;/pre&gt;

&lt;p&gt;　perl に限らず、テストの実行ツールは一般に、成功した場合はゼロ、失敗した場合は非ゼロを返します (そうしないと make test &amp;amp;&amp;amp; make install とか自動化できない)。この特性と cronlog の、非ゼロが返った場合だけ cron を経由してログをメールで送信する、という機能を組み合わせることで、テストコードが監視系に早変わりするのです。さらに外側で setlock -nX しているのは、５分間でテストが終了しなかった場合に、やはりエラーメールを送信するため。&lt;/p&gt;

&lt;p&gt;　以上のように、cronlog を使えば、プログラマが使い慣れたテストスートの一部として監視系を書くことができます。パストラックでは更に、リバースプロキシのログ監視を &lt;a href=&quot;http://github.com/kazuho/kaztools/blob/master/touch_if&quot;&gt;touch_if&lt;/a&gt; コマンドとテストコードを連動する形で実施するようにしています。どうぞご覧ください。&lt;/p&gt;</content:encoded>


<dc:subject>Perl</dc:subject>
<dc:subject>管理・運用</dc:subject>

<dc:creator>Oku Kazuho</dc:creator>
<dc:date>2010-01-18T15:03:54+09:00</dc:date>
</item>
<item rdf:about="http://developer.cybozu.co.jp/kazuho/2010/01/blockdiff-linux.html">
<title>blockdiff を使ったお手軽ホットバックアップ環境の構築 (Linux, MySQL, etc.)</title>
<link>http://developer.cybozu.co.jp/kazuho/2010/01/blockdiff-linux.html</link>
<description>　一昨日に開催された hbstudy #7 にバックアップの話を聞きに行ってきました。Amanda を中心にした話で、とても勉強になりました。が、設定がめんどくさそうだなぁ、とも。自分の需要にはあわな...</description>
<content:encoded>&lt;p&gt;　一昨日に開催された &lt;a href=&quot;http://heartbeats.jp/hbstudy/2009/12/hbstudy7.html&quot;&gt;hbstudy #7&lt;/a&gt; にバックアップの話を聞きに行ってきました。&lt;a href=&quot;http://zmanda.jp/amanda.html&quot;&gt;Amanda&lt;/a&gt; を中心にした話で、とても勉強になりました。が、設定がめんどくさそうだなぁ、とも。自分の需要にはあわない感じでした。&lt;/p&gt;

&lt;p&gt;　勉強会が終わったあとで、自作のバックアップスクリプト &lt;a href=&quot;http://github.com/kazuho/blockdiff&quot;&gt;blockdiff&lt;/a&gt; に関する話を何人かの方とさせていただいたのですが、思いのほか反応が良かったので、あらためて紹介したいと思います。&lt;/p&gt;

&lt;p&gt;　blockdiff は、一言でいうと、パーティションやデータベースのデータファイルの差分バックアップツールです。rsnapshot に似ていますが、rsnapshot ではデータベースのホットバックアップ不可能です。逆に blockdiff はディレクトリ単位でのバックアップには対応していないかわり、&lt;strong&gt;ファイルシステムやデータベースを、一貫性を保ちつつ実質無停止で差分バックアップすることができます&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;　blockdiff の具体的な特徴は以下のとおりです。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;設定ファイルが不要&lt;/li&gt;
&lt;p style=&quot;margin-left: 2em;&quot;&gt;複雑な設定がありません。コマンドライン (あるいは crontab) で、適当な引数をつけてバックアップコマンドを呼び出すだけの簡単インターフェイスです。コマンドラインで動作を制御するため、(ホットバックアップを含む) 様々なバックアップロジックを組むことも可能です。&lt;/p&gt;
&lt;li&gt;バックアップを取るサーバにソフトウェアのインストールが不要&lt;/li&gt;
&lt;p style=&quot;margin-left: 2em;&quot;&gt;ssh 経由でリモートサーバのバックアップを取ることができます。サーバにバックアップソフトウェアをインストールする必要はありません (バックアップを取るために必要なプログラムは自動的に送り込まれます) &lt;sup&gt;注1&lt;/sup&gt;&lt;/p&gt;
&lt;li&gt;フルバックアップと増分バックアップに対応&lt;/li&gt;
&lt;p style=&quot;margin-left: 2em;&quot;&gt;フルバックアップと増分バックアップに対応しています。また、下位レイヤのスクリプト (blockdiff_dump) を直接実行すれば、差分バックアップも可能です。&lt;/p&gt;
&lt;li&gt;ファイル単位、あるいは LVM スナップショットを使ったバックアップが可能&lt;/li&gt;
&lt;p style=&quot;margin-left: 2em;&quot;&gt;ファイル単位のバックアップと、LVM スナップショットを使ったホットバックアップに対応しています。&lt;/p&gt;
&lt;li&gt;MySQL のホットバックアップが可能&lt;/li&gt;
&lt;p style=&quot;margin-left: 2em;&quot;&gt;同梱の mysqllock コマンドと組み合わせることで、LVM スナップショットを使った MySQL データベースのホットバックアップが可能です。PostgreSQL については確認はしていませんが、ロックコマンドを使わなくてもバックアップが取れるんじゃないかと思います。&lt;/p&gt;
&lt;li&gt;LVM ベースの VM のホットバックアップが可能&lt;/li&gt;
&lt;p style=&quot;margin-left: 2em;&quot;&gt;LVM ベースの仮想ディスクを用いた Xen の DomU のホットバックアップが可能です&lt;sup&gt;注2&lt;/sup&gt;。私は使っていないので試していませんが、KVM の仮想マシンについても同等のことが可能だと思われます。LVM ベースではない VM についても、スナップショット機構によってはホットバックアップが可能だと思われます。&lt;/p&gt;
&lt;/ul&gt;

&lt;p&gt;　blockdiff を使った LVM ボリュームのバックアップ方法については &lt;a href=&quot;http://developer.cybozu.co.jp/kazuho/2009/11/lvm-d8f3.html&quot;&gt;Kazuho@Cybozu Labs: リモートからXenのDomUとかLVMやファイルを差分バックアップするスクリプトを書いた&lt;/a&gt; で触れたので、ここでは MySQL データベースをホットバックアップする場合の設定を紹介したいと思います。前提として、MySQL のデータが LVM ボリューム上に保存されている必要があります。&lt;/p&gt;

&lt;p&gt;　バックアップスクリプトは、以下のような感じになります。&lt;/p&gt;

&lt;pre style=&quot;border: 1px solid gray; margin: 1em 0pt; padding: 0.5em; background: rgb(238, 238, 238) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot;&gt;#! /bin/bash&lt;br /&gt;&lt;br /&gt;export BLOCKSIZE=16834&lt;br /&gt;export LVCREATE_PREFIX=&amp;quot;mysqllock --host=db-host --user=root --password=XXX&amp;quot;&lt;br /&gt;export YEARMONTH=`date &#39;+%Y%m&#39;`&lt;br /&gt;&lt;br /&gt;blockdiff_backup /var/backup/db-backup-$YEARMONTH bin/ssh_lvm_dump --gzip \&lt;br /&gt;&amp;nbsp; root@db-host /dev/mapper/logical_volume_of_mysql&lt;/pre&gt;

&lt;p&gt;このバックアップスクリプトは以下のことを行っています。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;バックアップのブロックサイズを InnoDB のブロックサイズである 16KB に設定&lt;/li&gt;
&lt;li&gt;スナップショットを取る瞬間に mysqllock コマンドを使って FLUSH TABLES WITH READ LOCK を使うことで、MyISAM テーブル等の一貫性のあるバックアップを実現&lt;/li&gt;
&lt;li&gt;１ヶ月毎にフルバックアップ。それ以内は増分バックアップ&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;　バックアップスクリプトを実行すると、最初に db-backup-YYYYMM.1.gz, db-backup-YYYYMM.1.md5, db_backup-YYYYMM.ver という３つのファイルが作成されます。YYYYMM.1.gz がバックアップデータ、YYYYMM1.md5 がブロック単位のチェックサム情報です。次に実行すると YYYYMM.2.* が、その次は YYYYMM.3.* が、という形で増分バックアップが増えていきます。最新のバックアップの番号は .ver ファイルが記憶しているので、バックアップが途中で失敗しても問題ありません。次回バックアップ時に壊れたバックアップファイルが上書きされます。&lt;/p&gt;

&lt;pre style=&quot;border: 1px solid gray; margin: 1em 0pt; padding: 0.5em; background: rgb(238, 238, 238) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot;&gt;% ls -l db-backup-201001*&lt;br /&gt;-rw-r--r-- 1 backup backup 50289166539 2010-01-01 05:35 db-backup-201001.1.gz&lt;br /&gt;-rw-r--r-- 1 backup backup&amp;nbsp; &amp;nbsp;131072004 2010-01-01 05:35 db-backup-201001.1.md5&lt;br /&gt;-rw-r--r-- 1 backup backup 10914423057 2010-01-02 04:32 db-backup-201001.2.gz&lt;br /&gt;-rw-r--r-- 1 backup backup&amp;nbsp; &amp;nbsp;131072004 2010-01-02 04:32 db-backup-201001.2.md5&lt;br /&gt;-rw-r--r-- 1 backup backup 13648250036 2010-01-03 04:33 db-backup-201001.3.gz&lt;br /&gt;-rw-r--r-- 1 backup backup&amp;nbsp; &amp;nbsp;131072004 2010-01-03 04:34 db-backup-201001.3.md5&lt;br /&gt;...&lt;br /&gt;-rw-r--r-- 1 backup backup&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; 3 2010-01-18 04:34 db-backup-201001.ver&lt;/pre&gt;

&lt;p&gt;　バックアップスクリプトが正しく動作することを確認したら、crontab を設定して毎日バックアップを取るようにします。&lt;/p&gt;

&lt;pre style=&quot;border: 1px solid gray; margin: 1em 0pt; padding: 0.5em; background: rgb(238, 238, 238) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot;&gt;0 4 * * * setlock -nX /var/backup/backup.lock cronlog -l /var/backup/backup.log -t -- /var/backup/backup.sh 2&gt;&amp;1&lt;/pre&gt;

&lt;p&gt;　ここでは、&lt;a href=&quot;http://cr.yp.to/daemontools.html&quot;&gt;daemontools&lt;/a&gt; の setlock コマンドを使って万が一の重複起動を抑止しています。また、&lt;a href=&quot;http://github.com/kazuho/kaztools&quot;&gt;kaztools&lt;/a&gt; の cronlog コマンドを使うことで、バックアップの進捗をログに保存しつつ、バックアップが失敗した場合は cron 経由でアラートメールが送信されるようになっています。&lt;/p&gt;

&lt;p&gt;　ちなみに、バックアップのログ (backup.log) は、毎日次のような感じで追記されていきます。データベースの停止期間 (アプリケーションからのクエリがロックされる期間) は 03:35:56 から 03:36:00 までの４秒間であり、実質無停止でのバックアップができていることがわかります。&lt;/p&gt;

&lt;pre style=&quot;border: 1px solid gray; margin: 1em 0pt; padding: 0.5em; background: rgb(238, 238, 238) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot;&gt;------------------------------------------------------------------------------&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:05:02 2010] backup-srv starting: /var/backup/backup.sh&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:05:02 2010] creating snapshot...&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:05:07 2010]&amp;nbsp; &amp;nbsp;Logical volume &amp;quot;lvm_dump&amp;quot; created&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:05:07 2010] running: bin/ssh_blockdiff_dump --gzip &amp;quot;root@db-host&amp;quot; &amp;quot;/dev/db/lvm_dump&amp;quot;...&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:19:22 2010] removing snapshot /dev/db/lvm_dump...&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:19:23 2010]&amp;nbsp; &amp;nbsp;Logical volume &amp;quot;lvm_dump&amp;quot; successfully removed&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:19:23 2010] backup completed successfully&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:19:23 2010] creating snapshot...&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:35:56 2010] issuing lock statement: FLUSH TABLES WITH READ LOCK&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:36:00 2010]&amp;nbsp; &amp;nbsp;Logical volume &amp;quot;lvm_dump&amp;quot; created&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:36:00 2010] issuing unlock statement: UNLOCK TABLES&lt;br /&gt;[Sat Jan&amp;nbsp; 9 03:36:00 2010] running: bin/ssh_blockdiff_dump --gzip &amp;quot;root@db-host&amp;quot; &amp;quot;/dev/x25m.1/lvm_dump&amp;quot;...&lt;br /&gt;[Sat Jan&amp;nbsp; 9 04:18:44 2010] removing snapshot /dev/x25m.1/lvm_dump...&lt;br /&gt;[Sat Jan&amp;nbsp; 9 04:18:46 2010]&amp;nbsp; &amp;nbsp;Logical volume &amp;quot;lvm_dump&amp;quot; successfully removed&lt;br /&gt;[Sat Jan&amp;nbsp; 9 04:18:46 2010] backup completed successfully&lt;br /&gt;[Sat Jan&amp;nbsp; 9 04:18:46 2010] command exited with code:0&lt;/pre&gt;

&lt;p&gt;　このように、blockdiff を使うことで VM 単位のバックアップだけでなく、データベースのホットバックアップも簡単に取ることができます。パストラックでは、これらバックアップスクリプトに処理を追加し、バックアップ中は統計処理を抑止するといったことも行っています。&lt;/p&gt;

&lt;p&gt;　blockdiff や kaztools は、いずれも私の github リポジトリ (&lt;a href=&quot;http://github.com/kazuho/&quot;&gt;github.com/kazuho&lt;/a&gt;) からダウンロードして perl Makefile.PL &amp;amp;&amp;amp; make all test &amp;amp;&amp;amp; make install でインストール可能です。あるいは &lt;a href=&quot;http://search.cpan.org/dist/App-NoPAN/&quot;&gt;nopan&lt;/a&gt; がインストールされていれば、nopan http://github.com/kazuho/blockdiff http://github.com/kazuho/kaztools と１コマンドでインストールすることができます。いずれも&lt;a href=&quot;http://pathtraq.com/&quot;&gt;パストラック&lt;/a&gt;で実際に運用しているツール群ですが、興味のある方は (at your own risk で) お試しあれ。&lt;/p&gt;

&lt;p&gt;
注1: バックアップを取るサーバに Perl 5.8 以降がインストールされている必要があります。また、公開鍵認証を用いて SSH ログインできる必要があります&lt;br /&gt;
注2: XenServer のスナップショット機能とは併用できません
&lt;/p&gt;</content:encoded>


<dc:subject>MySQL</dc:subject>
<dc:subject>Perl</dc:subject>
<dc:subject>PostgreSQL</dc:subject>
<dc:subject>管理・運用</dc:subject>

<dc:creator>Oku Kazuho</dc:creator>
<dc:date>2010-01-18T11:53:54+09:00</dc:date>
</item>


</rdf:RDF>
