BIND は DNSサーバで UNIX系システムでは事実上の標準と言えるほど有名です
ISCがソースの保守を行っていて 年に1回は新機能リリースをやっているようです
今回 BIND9 をインストールして 64bit環境 IPv6環境での動作検証を行います
検証環境
CPU
AMD PhenomII X4 905e (2.5GHz 4コア)
メモリ
16GB
OS
Gentoo-1.12.14ベース Linux-3.0 UTF-8
コンパイラ
gcc-4.5.2
Cライブラリ
glibc-2.13
ODBC
libiodbc-3.52.7
BerkeleyDB
5.1.25.NC
PostgreSQL
9.1
MySQL
5.5.15
Oracle
11g Express Edition Release2
LDAP
OpenLDAP-2.4.23
BIND
9.8.1
ここで なぜ(自宅に)DNSサーバが必要で DNSのIPv6化が何を指しているのかを説明します
まず IPv6ネットワークの状況ですが
フレッツルータから下の部分は 自宅LANの状況です
今回 IPv6対応の DNSサーバを構築するのが目的です
フレッツ網は IPv6も可能ですが インターネット上の他のIPv6網と分断されています (2011年状況)
従って インターネット上の他のIPv6ネットワークへは直接通信が届きません
自宅内に複数の 端末/サーバ/ルータ があってホスト名をつけたい場合
今回のように 「自宅にDNSサーバを立てる必要がある」のです
IPv6通信するのは 赤の矢印の部分です 通信は IPv6ですが
IPv4ホスト名(Aレコード)/IPv6ホスト名(AAAAレコード) どちらも解決できます
インターネットの IPv6通信は分断された状態ですが
フレッツ網の DNSサーバはどうやって 他IPv6網の名前情報にアクセスしているのでしょうか?
上図は IPv4通信の状況です
フレッツのDNSサーバは IPv4を使って IPv6/IPv4名前解決をしていると思われます
(フレッツ網内の仕組みは詳しくないので ひょっとしたら違うかも)
いずれにしても 自宅の IPv6/IPv4 DNS化は下記前提で行います
フレッツ網内の DNSサーバが IPv6(AAAA)/IPv4(A) どちらも解決可能
フレッツ網内の DNSサーバへ IPv6通信で問い合わせる (IPv4通信でも可能だが)
自宅DNSサーバは IPv6(AAAA)/IPv4(A) 解決可能 かつ IPv6通信/IPv4通信 可能
インストール
$ tar -xzf bind-9.8.1.tar.gz
$ cd bind-9.8.1
$ ./configure --prefix=/ram --localstatedir=/ram/var --with-openssl --enable-threads --enable-atomic --with-randomdev=/dev/urandom --enable-getifaddrs --with-dlz-postgres=yes --with-dlz-mysql=/usr/mysql --with-dlz-bdb=yes --with-dlz-filesystem=yes --with-dlz-ldap=yes --with-dlz-odbc=yes --with-dlz-stub=yes
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
〜
make[1]: Leaving directory `/ram/bind-9.8.1/doc'
rm -f *.o *.o *.lo *.la core *.core *-symtbl.c *tmp0 *tmp1 *tmp2
rm -rf .depend .libs
rm -f FAQ.tmp
$ make
making all in /home/admin/bind-9.8.1/make
make[1]: ディレクトリ `/home/admin/bind-9.8.1/make&apos に入ります
make[1]: ディレクトリ `/home/admin/bind-9.8.1/make' から出ます
〜
/home/admin/bind-9.8.1/bin/named/../../contrib/dlz/drivers/dlz_postgres_driver.c:487: undefined reference to `sdlzh_build_querystring'
/home/admin/bind-9.8.1/bin/named/../../contrib/dlz/drivers/dlz_postgres_driver.c:484: undefined reference to `sdlzh_build_querystring'
〜
/home/admin/bind-9.8.1/bin/named/../../contrib/dlz/drivers/dlz_odbc_driver.c:1404: undefined reference to `sdlzh_build_sqldbinstance'
collect2: ld はステータス 1 で終了しました
make[2]: *** [named] エラー 1
make[2]: ディレクトリ `/home/admin/bind-9.8.1/bin/named' から出ます
make[1]: *** [subdirs] エラー 1
make[1]: ディレクトリ `/home/admin/bind-9.8.1/bin' から出ます
make: *** [subdirs] エラー 1
$
大量の undefined referenceエラーが出ました bind-9.8.1固有のバグのようです
contrib/dlz/drivers/sdlz_helper.c を下記のように修正することで回避できます
52
53 #ifdef DLZ
54
↓
52
53 //#ifdef DLZ
54
530
531 #endif
↓
530
531 //#endif
再度 makeします
$ make
making all in /home/admin/bind-9.8.1/make
make[1]: ディレクトリ `/home/admin/bind-9.8.1/make' に入ります
make[1]: ディレクトリ `/home/admin/bind-9.8.1/make' から出ます
〜
making all in /home/admin/bind-9.8.1/doc/doxygen
make[2]: ディレクトリ `/home/admin/bind-9.8.1/doc/doxygen' に入ります
make[2]: ディレクトリ `/home/admin/bind-9.8.1/doc/doxygen' から出ます
make[1]: ディレクトリ `/home/admin/bind-9.8.1/doc' から出ます
$ su
# make install
making all in /home/admin/bind-9.8.1/make
make[1]: ディレクトリ `/home/admin/bind-9.8.1/make' に入ります
make[1]: ディレクトリ `/home/admin/bind-9.8.1/make' から出ます
〜
/bin/sh ./mkinstalldirs /usr/share/man/man1
/usr/bin/install -c isc-config.sh /usr/bin
/usr/bin/install -c -m 644 ./isc-config.sh.1 /usr/share/man/man1
/usr/bin/install -c -m 644 ./bind.keys /usr/etc
$
インストールされるファイルは下記の通りです
bin/:
dig host isc-config.sh nslookup nsupdate
etc/:
bind.keys
include/bind9:
check.h getaddresses.h version.h
include/dns:
acl.h ds.h message.h rdataslab.h tcpmsg.h
adb.h enumclass.h name.h rdatastruct.h time.h
byaddr.h enumtype.h ncache.h rdatatype.h tkey.h
cache.h events.h nsec.h request.h tsig.h
callbacks.h fixedname.h peer.h resolver.h ttl.h
cert.h iptable.h portlist.h result.h types.h
compress.h journal.h private.h rootns.h validator.h
db.h keyflags.h rbt.h rpz.h version.h
dbiterator.h keytable.h rcode.h sdb.h view.h
dbtable.h keyvalues.h rdata.h sdlz.h xfrin.h
diff.h lib.h rdataclass.h secalg.h zone.h
dispatch.h log.h rdatalist.h secproto.h zonekey.h
dlz.h master.h rdataset.h soa.h zt.h
dnssec.h masterdump.h rdatasetiter.h ssu.h
include/dst:
dst.h gssapi.h lib.h result.h
include/isc:
app.h formatcheck.h md5.h quota.h stdtime.h
assertions.h fsaccess.h mem.h radix.h string.h
atomic.h hash.h msgcat.h random.h symtab.h
base64.h heap.h msgs.h ratelimiter.h syslog.h
bind9.h hex.h mutex.h refcount.h task.h
bitstring.h hmacmd5.h mutexblock.h region.h taskpool.h
boolean.h httpd.h namespace.h resource.h thread.h
buffer.h int.h net.h result.h time.h
bufferlist.h interfaceiter.h netaddr.h resultclass.h timer.h
commandline.h iterated_hash.h netdb.h rwlock.h types.h
condition.h lang.h offset.h serial.h util.h
dir.h lex.h once.h sha1.h version.h
entropy.h lfsr.h ondestroy.h sha2.h xml.h
error.h lib.h os.h sockaddr.h
event.h list.h parseint.h socket.h
eventclass.h log.h platform.h stdio.h
file.h magic.h print.h stdlib.h
include/isccc:
alist.h cc.h events.h result.h symtab.h types.h version.h
base64.h ccmsg.h lib.h sexpr.h symtype.h util.h
include/isccfg:
aclconf.h cfg.h grammar.h log.h namedconf.h version.h
include/lwres:
context.h ipv6.h list.h lwpacket.h net.h platform.h version.h
int.h lang.h lwbuffer.h lwres.h netdb.h result.h
lib/:
libbind9.a libdns.a libisc.a libisccc.a libisccfg.a liblwres.a
sbin/:
arpaname dnssec-revoke lwresd named-journalprint
ddns-confgen dnssec-settime named nsec3hash
dnssec-dsfromkey dnssec-signzone named-checkconf rndc
dnssec-keyfromlabel genrandom named-checkzone rndc-confgen
dnssec-keygen isc-hmac-fixup named-compilezone
share/man/man1:
arpaname.1 dig.1 host.1 isc-config.sh.1 nslookup.1 nsupdate.1
share/man/man3:
lwres.3 lwres_gabnresponse_render.3
lwres_addr_parse.3 lwres_gai_strerror.3
lwres_buffer.3 lwres_getaddrinfo.3
lwres_buffer_add.3 lwres_getaddrsbyname.3
lwres_buffer_back.3 lwres_gethostbyaddr.3
lwres_buffer_clear.3 lwres_gethostbyaddr_r.3
lwres_buffer_first.3 lwres_gethostbyname.3
lwres_buffer_forward.3 lwres_gethostbyname2.3
lwres_buffer_getmem.3 lwres_gethostbyname_r.3
lwres_buffer_getuint16.3 lwres_gethostent.3
lwres_buffer_getuint32.3 lwres_gethostent_r.3
lwres_buffer_getuint8.3 lwres_getipnode.3
lwres_buffer_init.3 lwres_getipnodebyaddr.3
lwres_buffer_invalidate.3 lwres_getipnodebyname.3
lwres_buffer_putmem.3 lwres_getnamebyaddr.3
lwres_buffer_putuint16.3 lwres_getnameinfo.3
lwres_buffer_putuint32.3 lwres_getrrsetbyname.3
lwres_buffer_putuint8.3 lwres_gnba.3
lwres_buffer_subtract.3 lwres_gnbarequest_free.3
lwres_conf_clear.3 lwres_gnbarequest_parse.3
lwres_conf_get.3 lwres_gnbarequest_render.3
lwres_conf_init.3 lwres_gnbaresponse_free.3
lwres_conf_parse.3 lwres_gnbaresponse_parse.3
lwres_conf_print.3 lwres_gnbaresponse_render.3
lwres_config.3 lwres_herror.3
lwres_context.3 lwres_hstrerror.3
lwres_context_allocmem.3 lwres_inetntop.3
lwres_context_create.3 lwres_lwpacket_parseheader.3
lwres_context_destroy.3 lwres_lwpacket_renderheader.3
lwres_context_freemem.3 lwres_net_ntop.3
lwres_context_initserial.3 lwres_noop.3
lwres_context_nextserial.3 lwres_nooprequest_free.3
lwres_context_sendrecv.3 lwres_nooprequest_parse.3
lwres_endhostent.3 lwres_nooprequest_render.3
lwres_endhostent_r.3 lwres_noopresponse_free.3
lwres_freeaddrinfo.3 lwres_noopresponse_parse.3
lwres_freehostent.3 lwres_noopresponse_render.3
lwres_gabn.3 lwres_packet.3
lwres_gabnrequest_free.3 lwres_resutil.3
lwres_gabnrequest_parse.3 lwres_sethostent.3
lwres_gabnrequest_render.3 lwres_sethostent_r.3
lwres_gabnresponse_free.3 lwres_string_parse.3
lwres_gabnresponse_parse.3
share/man/man5:
named.conf.5 rndc.conf.5
share/man/man8:
ddns-confgen.8 dnssec-settime.8 named-checkconf.8 nsec3hash.8
dnssec-dsfromkey.8 dnssec-signzone.8 named-checkzone.8 rndc-confgen.8
dnssec-keyfromlabel.8 genrandom.8 named-compilezone.8 rndc.8
dnssec-keygen.8 isc-hmac-fixup.8 named-journalprint.8
dnssec-revoke.8 lwresd.8 named.8
var/run:
DNSサービスを開始/停止するのに使う start/stopスクリプトも作成しておきます
検証環境は Gentooベースのシステムのため下記内容 /etc/init.d/bind (0755) となります
#!/sbin/runscript
# Copyright 1999-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header$
PIDFILE=/var/run/named.pid
depend() {
need net.eth0
provide dns
}
start() {
ebegin "Starting bind"
/usr/local/sbin/named -u daemon
eend $?
}
stop() {
ebegin "Stopping bind"
/bin/kill `cat $PIDFILE`
eend $?
}
デーモンプロセスである named は daemonアカウントで動作させることにしています
ルートネームサーバのアドレスリストを取得しておきましょう
(ただし 今回の構成では実際に利用することはありません)
下記 2通りのいずれかの方法です
FTP ftp://ftp.nic.ad.jp/internic/domain/named.root から直接取得
digコマンドにより取得 dig @A.ROOT-SERVERS.NET. > /etc/namedb/named.root
named.root は下記のような内容になっています
; <<>> DiG 9.4.2 <<>> @A.ROOT-SERVERS.NET.
; (2 servers found)
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21878
;; flags: qr aa rd; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 14
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;. IN NS
;; ANSWER SECTION:
. 518400 IN NS m.root-servers.net.
. 518400 IN NS h.root-servers.net.
. 518400 IN NS b.root-servers.net.
. 518400 IN NS g.root-servers.net.
. 518400 IN NS f.root-servers.net.
. 518400 IN NS c.root-servers.net.
. 518400 IN NS a.root-servers.net.
. 518400 IN NS l.root-servers.net.
. 518400 IN NS d.root-servers.net.
. 518400 IN NS i.root-servers.net.
. 518400 IN NS k.root-servers.net.
. 518400 IN NS j.root-servers.net.
. 518400 IN NS e.root-servers.net.
;; ADDITIONAL SECTION:
m.root-servers.net. 3600000 IN A 202.12.27.33
m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
h.root-servers.net. 3600000 IN A 128.63.2.53
h.root-servers.net. 3600000 IN AAAA 2001:500:1::803f:235
b.root-servers.net. 3600000 IN A 192.228.79.201
g.root-servers.net. 3600000 IN A 192.112.36.4
f.root-servers.net. 3600000 IN A 192.5.5.241
f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
c.root-servers.net. 3600000 IN A 192.33.4.12
a.root-servers.net. 3600000 IN A 198.41.0.4
a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
l.root-servers.net. 3600000 IN A 199.7.83.42
l.root-servers.net. 3600000 IN AAAA 2001:500:3::42
d.root-servers.net. 3600000 IN A 128.8.10.90
;; Query time: 69 msec
;; SERVER: 198.41.0.4#53(198.41.0.4)
;; WHEN: Wed Oct 12 22:45:39 2011
;; MSG SIZE rcvd: 512
13個のルートネームサーバが登録されており
うちいくつかのサーバは AAAA つまり IPv6によるクエリに対応していることが分かります
ルートネームサーバの用途としては
自ネームサーバが管理していない 外部ドメインなどの名前解決の問い合わせが来た時に
自力でインターネットに名前解決を問い合わせる 最初の問い合わせ先になります
ただし検証環境の構成では
外部名前解決はプロバイダが提供しているネームサーバに問い合わせることになるので
named.root は実際利用することはありません
続いての準備ですが
rndcコマンドで管理オペレーションをする際の 認証設定を行います
鍵を生成してから 設定ファイルに反映させます
まず鍵の生成ですが 以下のいずれかの方法で行います
dnssec-keygenを使って鍵を作成するのが下記の方法です
$ dnssec-keygen -a HMAC-MD5 -b 512 -n USER -r /dev/urandom mydomain
Kmydomain.+157+15789
$ ls Kmydomain*
Kmydomain.+157+15789.key Kmydomain.+157+15789.private
$ cat Kmydomain.+157+15789.key
mydomain. IN KEY 0 3 157 3******************************************************* *****************************w==
deer@phenom /ram $ cat Kmydomain.+157+15789.private
Private-key-format: v1.3
Algorithm: 157 (HMAC_MD5)
Key: 3************************************************************************************w==
Bits: AAA=
Created: 20111013062944
Publish: 20111013062944
Activate: 20111013062944
$
上記2ファイルは 鍵の内容を一部伏せていますが HMAC-MD5自体が共通鍵方式なので内容は同じです
.private側の文字列を後で設定ファイルに取り込みます
別の手段として次の rndc-confgenコマンドを使う方が手順としては楽でしょう
$ su
# rndc-confgen -a -b 512 -k mydomain
wrote key file "/usr/etc/rndc.key"
# cat /usr/etc/rndc.key
# Start of rndc.conf
key "mydomain" {
algorithm hmac-md5;
secret "c************************************************************************************w==";
};
options {
default-key "mydomain";
default-server 127.0.0.1;
default-port 953;
};
# End of rndc.conf
# Use with the following in named.conf, adjusting the allow list as needed:
# key "mydomain" {
# algorithm hmac-md5;
# secret "c************************************************************************************w==";
# };
#
# controls {
# inet 127.0.0.1 port 953
# allow { 127.0.0.1; } keys { "mydomain"; };
# };
# End of named.conf
直接 rndc.key フォーマットの設定ファイルを出力してくれます
作成した鍵を 設定ファイルに反映させます
まず クライアント用の設定ですが /usr/etc/rndc.key もしくは /usr/etc/rndc.conf
を上記の内容で作成します
dnssec-keygenを使った場合は secretの箇所に .private の Key: 鍵データを貼り付けます
rndc-confgenを使った場合は /usr/etc/rndc.key がそのまま使えます
サーバ用の設定ですが /usr/etc/named.conf に keyセクションと controlsセクションを記述します
bindの設定も含めて下記内容となります
acl "mydomain4" {
127.0.0.1/32;
192.168.1.0/24;
};
acl "mydomain6" {
::1/128;
fe80::/64;
};
options {
directory "/usr/etc";
pid-file "/var/run/named.pid";
port 53;
max-cache-size 4m;
listen-on { mydomain4; };
listen-on-v6 { mydomain6; };
forwarders { 2408:**:****:0:2***:****:****:***9; };
};
key "mydomain" {
algorithm hmac-md5;
secret "c************************************************************************************w==";
};
controls {
inet ::1 allow { ::1; } keys { mydomain; };
};
zone "." in {
type hint;
file "named.root";
};
zone "mydomain" in {
type master;
file "mydomain.zone";
};
zone "0.0.127.in-addr.arpa" {
type master;
file "0.0.127.in-addr.arpa.zone";
};
zone "1.168.192.in-addr.arpa" {
type master;
file "1.168.192.in-addr.arpa.zone";
};
zone "0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.ip6.arpa" {
type master;
file "0.0.0.fe80.in-addr.arpa.zone";
};
optionsセンテンスの listen-onで IPv4用 IPv6用 のアクセスリストを指定しています
それぞれのアクセスリストには ループバックと DNSクエリを受け付けたいネットワークを指定します
(これで 該当するネットワークインターフェースで DNSクエリを受け付けるようになります)
optionsセンテンスの forwardersには 上流フレッツ網のDNSサーバを指定します
IPv6アドレスで指定していますが IPv4アドレスの指定も可能です
forwardersがないと namedは直接インターネットに問い合わせようとして失敗します
(フレッツ光では インターネットへの直接問い合わせを禁止しています)
keyセンテンスには 先ほど設定した rndc用のキーを指定します
また rndc接続許可アドレスを controlsセンテンスで設定しています
これで rndcコマンドを受け付けるようになります
後は zoneセンテンスで各種 IPv6/IPv4問い合わせに対する設定をしています
IPv6の設定は グローバルアドレスではなくリンクローカルアドレス(fe80::/64)を使っていますが
リンクローカルアドレスを設定するのは ルール違反です
今回 IPv6インターネットが使えるようになるまでの暫定措置と動作確認用です
各ゾーンファイルの内容は下記の通りです
mydomain.zone (正引き用)
$TTL 3600
@ IN SOA phenom.mydomain. postmaster.mydomain. (
2011102402; serial
3600; refresh
100; retry
604800; expire
86400; negative
)
IN NS phenom4.mydomain.
IN MX 10 phenom4.mydomain.
aterm4 IN A 192.168.1.1
aterm IN AAAA fe80::2***:****:****:***9
phenom4 IN A 192.168.1.254
phenom IN AAAA fe80::1***:****:****:***a
0.0.127.in-addr.arpa.zone (IPv4逆引き)
$TTL 3600
@ IN SOA phenom.mydomain. postmaster.mydomain. (
2011102003; serial
3600; refresh
900; retry
604800; expire
86400; negative
)
IN NS phenom4.mydomain.
IN MX 10 phenom4.mydomain.
1 IN PTR localhost-v4.mydomain.
1.168.192.in-addr.arpa.zone (IPv4逆引き)
$TTL 3600
@ IN SOA phenom.mydomain. postmaster.mydomain. (
2011102002; serial
3600; refresh
900; retry
604800; expire
86400; negative
)
IN NS phenom.mydomain.
IN MX 10 phenom.mydomain.
1 IN PTR aterm4.mydomain.
254 IN PTR phenom4.mydomain.
0.0.0.fe80.in-addr.arpa.zone (IPv6逆引き)
$TTL 3600
@ IN SOA phenom.mydomain. postmaster.mydomain. (
2011101802; serial
3600; refresh
900; retry
604800; expire
86400; negative
)
IN NS phenom.mydomain.
IN MX 10 phenom.mydomain.
9.*.*.*.*.*.*.*.*.*.*.*.*.*.*.2 IN PTR aterm.mydomain.
a.*.*.*.*.*.*.*.*.*.*.*.*.*.*.1 IN PTR phenom.mydomain.
IPv6アドレスの一部は伏字にしています
現在 aterm(ルータ)と phenom(DNSサーバ自身)の設定のみですが
後で XBox360 や Wii も設定します
クライアント設定 も行っておきましょう
Windowsであれば ネットワークのプロパティ画面から
UNIX系であれば /etc/resolv.conf を設定します
動作確認
namedを起動します
# /etc/init.d/named start
* Starting bind ... [ ok ]
# netstat -a | grep domain
tcp 0 0 phenom4.mydomain:domain *:* LISTEN
tcp 0 0 localhost:domain *:* LISTEN
tcp6 0 0 phenom.mydomain:domain [::]:* LISTEN
tcp6 0 0 localhost:domain [::]:* LISTEN
udp 0 0 phenom4.mydomain:domain *:*
udp 0 0 localhost:domain *:*
udp6 0 0 phenom.mydomain:domain [::]:*
udp6 0 0 localhost:domain [::]:*
Active UNIX domain sockets (servers and established)
#
Linuxクライアントで名前解決できることを確認します
$ ping6 -I eth0 -c 2 aterm
PING aterm(aterm.mydomain) from fe80::1***:****:****:***a eth0: 56 data bytes
64 bytes from aterm.mydomain: icmp_seq=1 ttl=64 time=0.151 ms
64 bytes from aterm.mydomain: icmp_seq=2 ttl=64 time=0.152 ms
--- aterm ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.151/0.151/0.152/0.012 ms
$ ping6 -c 2 ds.test-ipv6.jp
PING ds.test-ipv6.jp(2406:800:3:141::196) 56 data bytes
--- ds.test-ipv6.jp ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 999ms
$
自宅内ホストへの ping疎通はOKですが リンクローカルアドレスを設定しているので -I 指定が必要です
インターネット上の IPv6テストサイト(ds.test-ipv6.jp)は疎通しませんでした
IPv6アドレスまでは解決されましたが肝心の IPv6ネットワークが分断されているためです
IPv4も確認しておきましょう
$ ping -c 2 aterm4
PING aterm4.mydomain (192.168.1.1) 56(84) bytes of data.
64 bytes from aterm4.mydomain (192.168.1.1): icmp_req=1 ttl=64 time=0.134 ms
64 bytes from aterm4.mydomain (192.168.1.1): icmp_req=2 ttl=64 time=0.129 ms
--- aterm4.local ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.129/0.131/0.134/0.011 ms
$ ping -c 2 www.google.com
PING www.l.google.com (74.125.31.104) 56(84) bytes of data.
64 bytes from tb-in-f104.1e100.net (74.125.31.104): icmp_req=1 ttl=44 time=36.6 ms
64 bytes from tb-in-f104.1e100.net (74.125.31.104): icmp_req=2 ttl=44 time=37.4 ms
--- www.l.google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 36.630/37.040/37.450/0.410 ms
$
IPv4 各ネットワークも通常通り疎通します
Windowsの コマンドプロンプトからも確認しておきます
C:\\Users\\admin>nslookup phenom
サーバー: phenom.mydomain
Address: fe80::1***:****:****:***a
名前: phenom.mydomain
Address: fe80::1***:****:****:***a
C:\\Users\\admin>nslookup phenom4
サーバー: phenom.mydomain
Address: fe80::1***:****:****:***a
名前: phenom4.mydomain
Address: 192.168.1.254
C:\\Users\\admin>nslookup ds.test-ipv6.com
サーバー: phenom.mydomain
Address: fe80::1***:****:****:***a
権限のない回答:
名前: ds.test-ipv6.com
Addresses: 2001:470:1:18::2
216.218.228.114
C:\\Users\\admin>
IPv6 IPv4 どちらのクエリにも対応できています
自宅の IPv6環境を構築しました
プロバイダの DNSサーバまでIPv6で通信して IPv6アドレスの解決までできることを確認しました
IPv6が利用可能な環境はすぐ近くまで来ています
Webサーバとして有名な Apacheを64bit+IPv6環境で検証します
Apache は Windows系 UNIX系で動作するメジャーな Webサーバです
オープンソース財団の The Apache Software Foundation も設立され
Webサーバ以外のオープンソースソフトも精力的に開発しています
上記 The Apache Software Foundationのトップページですが
多数のプロジェクトが管理されていることが分かります
今回 HTTP Server をインストールして 64bit環境 IPv6環境での動作検証を行います
検証環境
CPU
AMD PhenomII X4 905e (2.5GHz 4コア)
メモリ
16GB
OS
Gentoo-1.12.14ベース Linux-3.0 UTF-8
コンパイラ
gcc-4.5.2
Cライブラリ
glibc-2.13
Perl
5.12.2
PHP
SQLite
autoconf-3070800
BerkeleyDB
5.1.25.NC
PostgreSQL
9.1
MySQL
5.5.15
Oracle
11g Express Edition Release2
LDAP
OpenLDAP-2.4.23
Apache httpd
2.2.21
Apache apr
1.4.5
Apache apr-iconv
1.2.1
Apache apr-util
1.3.12
インストール
Apache(本家) から Stable Releaseをダウンロードします
ダウンロードしたソースを一時ディレクトリに展開します
$ tar -xjf httpd-2.2.21.tar.bz2
$ cd httpd-2.2.21
$ ls -F srclib/
Makefile.in apr/ apr-util/ pcre/
$
srclib/ に含まれている apr apr-util のパッケージを先にインストールする必要があります
これらプログラムは APR(Aapche Portable Runtime)と呼ばれ
OS間の差異を吸収する 共通ライブラリとして機能します
(具体的には メモリ確保 I/O ライブラリリンク スレッド 時刻 ユーザID など)
srclib/ に含まれていない apr-iconv も導入しておきたいので
apr apr-iconv apr-util をまとめて Portable Runtime Project
からダウンロードしておきましょう
aprのインストールは下記のように行いました
$ ./configure --prefix=/usr/apache --enable-threads
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
Configuring APR library
〜
config.status: creating apr-1-config
config.status: creating apr.pc
config.status: creating test/Makefile
config.status: creating test/internal/Makefile
config.status: creating include/arch/unix/apr_private.h
config.status: executing default commands
$ make
make[1]: ディレクトリ `/home/admin/apr-1.4.5' に入ります
〜
make[1]: ディレクトリ `/home/admin/apr-1.4.5' から出ます
$ su
# make install
make[1]: ディレクトリ `/home/admin/apr-1.4.5' に入ります
make[1]: `local-all' に対して行うべき事はありません.
make[1]: ディレクトリ `/home/admin/apr-1.4.5' から出ます
〜
/usr/bin/install -c -m 644 build/apr_rules.out /usr/apache/build-1/apr_rules.mk
/usr/bin/install -c -m 755 apr-config.out /usr/apache/bin/apr-1-config
#
ビルドを補助するためのコマンドで apr-1-config が使えるようになります
apr-iconvのインストールは apr-utilのインストールと同時に行います
そのためここでは アーカイブの展開だけしておきます
$ tar -xzf apr-iconv-1.2.1.tar.gz
$
続いて apr-utilのインストールを下記のように行いました
$ tar -xzf apr-util-1.3.12.tar.gz
$ cd apr-util-1.3.12
$ ./configure --prefix=/usr/apache --with-apr=/usr/apache --with-apr-iconv=../apr-iconv-1.2.1 --with-sqlite3=/usr --with-dbm=db51 --with-pgsql=/usr --with-mysql=/usr/mysql --with-oracle=$ORACLE_HOME --with-odbc=/usr --with-ldap=/usr
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
checking for a BSD-compatible install... /usr/bin/install -c
checking for working mkdir -p... yes
〜
config.status: creating include/apu_want.h
config.status: creating test/Makefile
config.status: creating include/private/apu_config.h
config.status: executing default commands
$ make
Making all in ../apr-iconv-1.2.1
make[1]: ディレクトリ `/home/admin/apr-iconv-1.2.1' に入ります
(cd lib; make CPPFLAGS=" ")
〜
dbd/apr_dbd_odbc.c: In function ‘odbc_start_transaction':
dbd/apr_dbd_odbc.c:1178:32: 警告: 異なるサイズの整数からポインタにキャストされました
/bin/sh /usr/apache/build-1/libtool --silent --mode=link gcc -g -O2 -pthread -release 1 -module -rpath /home/admin/lib/apr-util-1 -o dbd/apr_dbd_odbc.la dbd/apr_dbd_odbc.lo -L/usr/lib -lodbc
make[1]: ディレクトリ `/home/admin/apr-util-1.3.12' から出ます
$ su
# make install
/usr/apache/build-1/mkdir.sh /home/admin/lib/apr-util-1
Making all in ../apr-iconv-1.2.1
〜
/usr/bin/install -c -m 644 aprutil.exp /usr/apache/lib
/usr/bin/install -c -m 755 apu-config.out /usr/apache/bin/apu-1-config
#
apr-iconv関連では apriconv のコマンドが利用できるようになります
あと /usr/apache/lib/iconv/ 配下にやたらと各国語用のモジュールが追加されます
apr-util関連では apu-1-config がビルド補助用に使えるようになり
/usr/apache/lib/apr-util-1/ に各データベース接続用のモジュールが追加されます
–with-apr-iconv の指定により apr-iconvも同時にビルドされますが
インストールされた apu-1-config に修正が必要でした
(apu-1-config –libs とコマンドを叩くと apr-iconv関連のパス修正が必要と分かるでしょう)
29
30 LIBS="/home/admin/apr-util-1.3.12/../apr-iconv-1.2.1/lib/libapriconv.la -lexpat"
31 INCLUDES="/home/admin/apr-util-1.3.12/../apr-iconv-1.2.1/include "
32 LDFLAGS=""
LIBSの部分と INCLUDESの部分に ソースディレクトリが指定されてしまっているので修正します
下記のように修正しました
29
30 LIBS="/usr/apache/lib/libapriconv-1.la -lexpat"
31 INCLUDES=""
32 LDFLAGS=""
また検証環境では Oracleが認識されず configure前に下記作業が必要でした
# cd $ORACLE_HOME/lib
# ln -s libclntsh.so.11.1 libclntsh.s
つまり -lclntsh 付きの gcc がコンパイルできる必要があるのです
Oracleを使っているのに lib/apr-util-1/に apr_dbd_oracle〜 が見付からない場合は
上記の対応後 apr-utilsの再ビルドが必要です
以上でようやく apache本体のビルドが可能となります
$ tar -xjf httpd-2.2.21.tar.bz2
$ cd httpd-2.2.21/
$ ./configure --prefix=/usr/apache --localstatedir=/var --enable-suexec --with-suexec-caller=www --enable-so --enable-modules="most" --enable-mods-shared="most"
checking for chosen layout... Apache
checking for working mkdir -p... yes
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
Configuring Apache Portable Runtime library ...
〜
config.status: creating build/rules.mk
config.status: creating build/pkg/pkginfo
config.status: creating build/config_vars.sh
config.status: creating include/ap_config_auto.h
config.status: executing default commands
$ make
Making all in srclib
make[1]: ディレクトリ `/home/admin/httpd-2.2.21/srclib' に入ります
Making all in pcre
〜
/usr/apache/build-1/libtool --silent --mode=link gcc -g -O2 -pthread -o suexec suexec.lo
make[2]: ディレクトリ `/home/admin/httpd-2.2.21/support' から出ます
make[1]: ディレクトリ `/home/admin/httpd-2.2.21' から出ます
$ su
# make install
Making install in srclib
make[1]: ディレクトリ `/home/admin/httpd-2.2.21/srclib" に入ります
〜
mkdir /usr/apache/man/man1
mkdir /usr/apache/man/man8
mkdir /usr/apache/manual
make[1]: ディレクトリ `/home/deer/admin/httpd-2.2.21" から出ます
#
configureオプションですが –enable-so は動的モジュール化するのに必須です
–enable-modules="most" –enable-mods-shared="most"
で Apacheのオプション機能をほとんど有効化しモジュール化しています
$ ls /usr/apache/modules/
httpd.exp mod_authz_user.so mod_include.so
mod_actions.so mod_autoindex.so mod_info.so
mod_alias.so mod_cgi.so mod_log_config.so
mod_asis.so mod_dav.so mod_logio.so
mod_auth_basic.so mod_dav_fs.so mod_mime.so
mod_auth_digest.so mod_dbd.so mod_negotiation.so
mod_authn_anon.so mod_deflate.so mod_reqtimeout.so
mod_authn_dbd.so mod_dir.so mod_rewrite.so
mod_authn_dbm.so mod_dumpio.so mod_setenvif.so
mod_authn_default.so mod_env.so mod_speling.so
mod_authn_file.so mod_expires.so mod_status.so
mod_authz_dbm.so mod_ext_filter.so mod_substitute.so
mod_authz_default.so mod_filter.so mod_suexec.so
mod_authz_groupfile.so mod_headers.so mod_userdir.so
mod_authz_host.so mod_ident.so mod_version.so
mod_authz_owner.so mod_imagemap.so mod_vhost_alias.so
$
特に小容量の Apacheを作りたいなどカスタマイズの必要があれば
–enable-modules="alias cgi" のように個別に指定することも可能です
続いて Apache用の start/stopスクリプトを用意しましょう
下記で紹介するのは Gentoo形式に従ったスクリプトですが
Apacheには apachectlという管理コマンドが付属しているのでシンプルな記載になります
#!/sbin/runscript
# Copyright 1999-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header$
depend() {
need net.eth0
}
start() {
ebegin "Starting apache"
/usr/apache/bin/apachectl start
eend $?
}
stop() {
ebegin "Stopping apache"
/usr/apache/bin/apachectl stop
eend $?
}
次に Apacheの設定ファイルをカスタマイズします
conf/httpd.conf が設定ファイルです
最近の Apacheはモジュールに関する設定を conf/extra/ に分けてインポートする記述のため
httpd.conf本体は だいぶ軽量化しています
httpd.confの修正点は下記の通りです
httpd実行アカウントを指定します www のアカウントが既に存在していたので利用しました
ServerAdmin www@mydomain
ServerName www.mydomain:80
ServerAdminには管理者メールアドレスを指定します
ServerNameは 公開するHPのFQDNとポート番号を指定します ここは httpdの動作に必須の項目です
(mydomainの DNSに wwwホスト設定の追加もしておきます)
とりあえず最小限の設定は以上です まずは Apacheが動作するかを確認しましょう
# /etc/init.d/apache start
* Caching service dependencies ... [ ok ]
* Starting apache ... [ ok ]
#
IPv6クライアントの検証ページ でApacheの正常動作を確認しました
(書きかけですが とりあえずここまで)
PostgreSQLは 高機能なオープンソースRDBMS(データベース)です
PostgreSQL は MySQL と 肩を並べるほどの高機能なオープンソースRDBMSです
日本語環境も充実しているので 日本での普及も進んでいるようです
今回 64bit環境 IPv6環境での動作検証を行います
検証環境
CPU
AMD PhenomII X4 905e (2.5GHz 4コア)
メモリ
16GB
OS
Gentoo-1.12.14ベース Linux-3.0 UTF-8
コンパイラ
gcc-4.5.2
Cライブラリ
glibc-2.13
Perl
5.12.2
TCL
8.5.9
libxml
libxml2-sources-2.7.8
libxslt
libxslt-1.1.26
PAM
Linux-PAM-1.1.3
SSL
openssl-1.0.0d
OpenLDAP
2.4.23
PostgreSQL
9.1
インストール
ここでのインストール作業は 主に以下の流れを解説しています
PostgreSQLソースパッケージのダウンロード
ソースコードからのビルドと PostgreSQLバイナリファイル郡のインストール
postgresql.conf環境設定 start/stop起動スクリプトの設定
データベース領域の新規作成
postmasterの起動
早速 PostgreSQLのダウンロード サイトからソースコードをダウンロードします
ここではソースコードからビルドしますが
パッケージ管理機構を持つシステム用にパッケージ提供もされています
$ tar -xjf postgresql-9.1.0.tar.bz2
$ cd postgresql-9.1.0
$ ls
COPYRIGHT HISTORY Makefile aclocal.m4 configure contrib src
GNUmakefile.in INSTALL README config configure.in doc
$ ./configure --prefix=/usr --datadir=/usr/share/pgsql --enable-nls --with-pam --with-libxml --with-libxslt --with-perl --with-tcl --with-ldap --with-openssl
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking which template to use... linux
checking whether to build with 64-bit integer date/time support... yes
checking whether NLS is wanted... yes
checking for default port number... 5432
checking for block size... 8kB
checking for segment size... 1GB
checking for WAL block size... 8kB
checking for WAL segment size... 16MB
checking for gcc... gcc
〜
config.status: linking src/backend/port/unix_latch.c to src/backend/port/pg_latch.c
config.status: linking src/backend/port/dynloader/linux.h to src/include/dynloader.h
config.status: linking src/include/port/linux.h to src/include/pg_config_os.h
config.status: linking src/makefiles/Makefile.linux to src/Makefile.port
$ make
make -C src all
make[1]: ディレクトリ `/home/admin/postgresql-9.1.0/src' に入ります
make -C port all
make[2]: ディレクトリ `/home/admin/postgresql-9.1.0/src/port' に入ります
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wformat-security -fno-strict-aliasing -fwrapv -I../../src/port -DFRONTEND -I../../src/include -D_GNU_SOURCE -I/usr/include/libxml2 -c -o strlcat.o strlcat.c
〜
$ su
# make install
〜
# make install-docs
〜
#
–datadir は設定ファイルの置き場所となります (データベース設置場所ではありません)
また事前に libxml2 libxslt など関連ライブラリがインストールされている必要があります
さらに検証した PostgreSQL-9.1 ではドキュメント類のインストールに
make install-docs が必要でした
次に システム管理者権限の環境変数設定を行っておきます PGLIB PGDATA の2つです
下記の設定を /etc/profile 等に追記してシステムログイン時に反映されるようにします
PGLIB=/usr/lib
PGDATA=/var/db/pgsql
PGDATAにデータベース領域をディレクトリで指定します
今後 /var/db/pgsql/ にデータベースを作成しメインで使っていくため指定しています
最後に PostgreSQLを起動/停止するための start/stopスクリプトを作成します
スクリプトの書き方は ディストリビューションによるので下記の例は参考程度のものです
下記は Gentoo用 /etc/init.d/pgsql (root 0755)
#!/sbin/runscript
# Copyright 1999-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header$
depend() {
need net.eth0
after apache
provide pgsql
}
start() {
ebegin "Starting PostgreSQL"
su adm -s /usr/bin/bash -c "/usr/bin/pg_ctl start -w -D /var/db/pgsql -s"
eend $?
}
stop() {
ebegin "Stopping MySQL"
su adm -s /usr/bin/bash -c "/usr/bin/pg_ctl stop -D /var/db/pgsql -s -m fast"
eend $?
}
restart() {
ebegin "Restarting MySQL"
su adm -s /usr/bin/bash -c "/usr/bin/pg_ctl restart -w -D /var/db/pgsql -s -m fast"
eend $?
}
status() {
su adm -s /usr/bin/bash -c "/usr/bin/pg_ctl status -D /var/db/pgsql"
exit $?
}
基本的に -D データベース領域 を指定して pg_ctl にコマンドを渡す形です
複数のデータベースディレクトリを運営する場合は その分 pg_ctlの行が増えるイメージです
(検証環境では /var/db/pgsql のみの運営とします)
stop や restart で指定している -m fast はシャットダウンモードの指定です
smart(クライアント利用終了待ち) fast(クライアント強制切断) immediate(強制終了)など
3通りモードがあります (詳しくは pg_ctl –helpで)
admアカウントをデータベース管理アカウントとして pg_ctlの各種処理を行っています
(MySQLも admアカウントで運営しているので今回流用しました
通常なら postgresアカウントを作って使うのが一般的です)
以上がインストールまでの一通りの作業です
データベースの運営
ここでは データベースの初期化 設定 IPv6接続確認 まで紹介します
まずは データベースの管理についてですが
PostgreSQLは postmaster 1プロセス毎に 1データベース領域(=ディレクトリ)を管理します
ディレクトリの中に データベース(複数) 各種ログ 設定ファイル が含まれます
ここでは先ほどの start/stopスクリプトで定義したとおり
admアカウントを管理アカウントとする /var/db/pgsql/ を初期化します
# mkdir /var/db/pgsql
# chown adm /var/db/pgsql
# su adm -s /usr/bin/bash -c "initdb $PGDATA"
データベースシステム内のファイルの所有者は"adm"ユーザでした。
このユーザがサーバプロセスを所有しなければなりません。
データベースクラスタはロケールja_JP.utf8で初期化されます。
デフォルトのデータベース符号化方式はUTF8に設定されました。
initdb: ロケール"ja_JP.utf8"用の適切なテキスト検索設定が見つかりません
デフォルトのテキスト検索設定はsimpleに設定されました。
ディレクトリ/var/db/pgsqlの権限を設定しています ... ok
サブディレクトリを作成しています ... ok
デフォルトのmax_connectionsを選択しています ... 100
デフォルトの shared_buffers を選択しています ... 24MB
設定ファイルを作成しています ... ok
〜
警告: ローカル接続向けに"trust"認証が有効です。
pg_hba.confを編集する、もしくは、次回initdbを実行する時に-Aオプショ
ンを使用することで変更することができます。
成功しました。以下を使用してデータベースサーバを起動することができます。
postmaster -D /var/db/pgsql
または
pg_ctl -D /var/db/pgsql -l logfile start
#
ここでは initdbコマンドを直接叩きましたが
pg_ctlからでも同様のことができるので pg_ctlに統一したほうが覚えやすいかもしれません
/var/db/pgsql/ 内が初期化されデータベース領域を利用する準備が整いました
# ls /var/db/pgsql/
PG_VERSION pg_hba.conf pg_serial pg_twophase postmaster.pid
base pg_ident.conf pg_stat_tmp pg_xlog
global pg_multixact pg_subtrans postgresql.conf
pg_clog pg_notify pg_tblspc postmaster.opts
#
ユーザ管理についてですが この時点では
データベース管理ユーザとして initdbを行ったアカウント adm が設定されています
次に設定ファイル postgresql.conf pg_hba.conf pg_ident.conf をカスタマイズします
まず postgresql.conf から設定します
以下は追記/編集した行のみの情報です
data_directory = '/var/db/pgsql'
hba_file = '/var/db/pgsql/pg_hba.conf'
ident_file = '/var/db/pgsql/pg_ident.conf'
listen_addresses = 'localhost,fe80::1***:****:****:***a%eth0'
data_directory はデータベース領域そのものを表します
hba_file は pg_hba.conf の置き場所を指定します
ident_file は pg_ident.conf の置き場所を指定しますが
ident認証方式を選択したときに利用されるだけで 今回の検証では ident認証方式は使いません
listen_address は 接続を行うインターフェースを指定するものです
デフォルトは 'localhost' となり外部ホストから接続を受け付けません
IPアドレスを指定することでそのIPで listen()するようになります
(ちなみに PostgreSQL7系まで使われていた tcpip_socket は廃止となっています)
今回 localhost も /etc/hosts では ::1 になっているので完全な IPv6仕様です
続いて認証に関する設定は pg_hba.conf 内で設定します
local all all trust
host all all 127.0.0.1/32 trust
host all all ::1/128 trust
host all gamer fe80::1***:****:****:***a/64 md5
上3行はローカルホストからの接続設定で 全データベースユーザを無条件に利用可能(trust)
最後1行が追加行で IPv6アドレスのみ許可 パスワード認証(md5)も実施する設定です
(IPv6のアドレスの箇所は伏字で標記しています)
IPv6部分はリンクローカルアドレスを使うことでグローバルからのパケットは届かない仕組みです
gamerというアカウントに制限しているので 後ほど gamerアカウントを作成することにします
pg_ident.conf は今回使いません
以上で データベース領域の初期化と設定が完了です 早速 postmaster を起動しましょう
# /etc/init.d/pgsql start
* Starting PostgreSQL ...
/usr/bin/postgres: /lib64/libz.so.1: no version information available (required by /usr/lib64/libxml2.so.2)
/usr/bin/postgres: /lib64/libz.so.1: no version information available (required by /usr/lib64/libxml2.so.2)
LOG: データベースシステムは 2011-09-19 22:52:24 UTC にシャットダウンしました
LOG: データベースシステムの接続受付準備が整いました。
LOG: 自動バキュームランチャプロセス [ ok ]
# netstat -an | grep 5432
tcp6 0 0 fe80::1***:***:**:5432 :::* LISTEN
tcp6 0 0 ::1:5432 :::* LISTEN
unix 2 [ ACC ] STREAM LISTENING 43186 /tmp/.s.PGSQL.5432
#
IPv6で接続が可能な状態となっています ローカルホストから UNIXドメインソケット接続も可能です
ポート番号も 5432 でデフォルトのままです
(複数の postmasterを運用する場合カスタマイズする必要あります)
データベース領域に データベースを1つ追加します games という名前で作成します
$ createdb -h localhost -U adm games
$
-h localhost は接続先データベースホストを指定します localhostならば省略可能です
-U adm は指定必要です データベース管理権限ユーザを指定します
追加ユーザも作っておきましょう
pg_hba.conf では gamer を外部接続用に定義しているので gamerユーザを作成します
$ createuser -U adm gamer
新しいロールをスーパーユーザにしますか? (y/n)n
新しいロールに対してデータベースを作成する権限を与えますか? (y/n)n
新しいロールに対して別のロールを作成する権限を与えますか? (y/n)n
$
-P オプションでパスワードを同時に設定することもできますが 次のように DDLで設定します
$ psql -U adm games
psql (9.1.0)
"help" でヘルプを表示します.
games=# alter user gamer encrypted password 'gamer';
ALTER ROLE
games=# \\q
$
データベースに接続するために psql コマンドを使いました
データベース接続後 サブシェルが開いて各種コマンドが発行できます
とりあえずローカルホスト上でデータベースに接続できることを確認し
gamerのパスワードを設定しました
では IPv6接続の検証を行います 別ホストの端末から psqlで接続します
$ psql -U gamer -h fe80::1***:****:****:***a%eth0 games
Password for user gamer:
Welcome to psql 8.3.0 (server 9.1.0), the PostgreSQL interactive terminal.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
WARNING: You are connected to a server with major version 9.1,
but your psql client is major version 8.3. Some backslash commands,
such as \d, might not work properly.
games=> \\q
$
psql に -h オプションで外部ホストを明示します Linuxでは %eth0 も必要でした
別ホスト側が PostgreSQL-8.3.0 を使っていたので警告が表示されていますが
IPv6での接続性は OKです
ただし 以降のデータベース操作検証は PostgreSQL-9.1.0側のサーバに戻って実施します
理由は別ホスト側の文字コードが EUC-JP サーバ側の UTF-8 と食い違っているため
文字化けするのです
テーブルの作成と動作検証
gamesデータベースまで作成したので
実際にレトロ系テレビゲームのデータを投入して 各種検索もデモします
サンプルデータ tvgames.zip (EUC-JP) をデータベース化します
$ eunzip tvgames.zip
Archive: tvgames.zip
inflating: tvgames.txt
$ head -n 10 tvgames.txt | iconv -f euc-jp
ドンキーコング,FC,任天堂,4500,1983-07-15
ドンキーコングJR.,FC,任天堂,4500,1983-07-15
ポパイ,FC,任天堂,4500,1983-07-15
五目ならべ [連珠],FC,任天堂,4500,1983-08-27
麻雀,FC,任天堂,4500,1983-08-27
マリオブラザーズ,FC,任天堂,4500,1983-09-09
ポパイの英語遊び,FC,任天堂,4500,1983-11-22
ベースボール,FC,任天堂,4500,1983-12-07
ドンキーコングJR. の算数遊び,FC,任天堂,4500,1983-12-12
テニス,FC,任天堂,4500,1984-01-14
$
ファミコンから プレイステーション1まで 全11429タイトルを納めているので
検証用のデータベース素材としてお手頃です
このデータを格納するテーブルを作成します
$ psql -U gamer games
psql (9.1.0)
"help" でヘルプを表示します.
games=> create table tvgames ( name text, plathome text, company text, price int, release_date date );
CREATE TABLE
games=> \\dt
リレーションの一覧
スキーマ | 名前 | 型 | 所有者
----------+---------+----------+--------
public | tvgames | テーブル | gamer
(1 行)
games=> \\d tvgames
テーブル "public.tvgames"
カラム | 型 | 修飾語
--------------+---------+--------
name | text |
plathome | text |
company | text |
price | integer |
release_date | date |
games=> \\q
$
\\dt と叩けば定義されているテーブルを一覧で確認できます
\\d テーブル名 でテーブルの定義も見れます
サンプル tvgames.txtを insert文に加工して SQL投入できるようにします
$ iconv -f euc-jp -t utf-8 tvgames.txt | sed "s/'/''/g" | sed "s/^\\(.*\\),\\(.*\\),\\(.*\\),\\(.*\\),\\(.*\\)$/insert into tvgames ( name, plathome, company, price, release_date ) values ( '\\1', '\\2', '\\3', \\4, '\\5' );/" | less -r > tvgame_insert.txt
$ head -n 10 tvgame_insert.txt
insert into tvgames ( name, plathome, company, price, release_date ) values ( '', 'FC', '任天堂', 4500, '1983-07-15' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( 'JR.', 'FC', '任天堂', 4500, '1983-07-15' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( '', 'FC', '任天堂', 4500, '1983-07-15' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( ' [連珠]', 'FC', '任天堂', 4500, '1983-08-27' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( '', 'FC', '任天堂', 4500, '1983-08-27' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( '', 'FC', '任天堂', 4500, '1983-09-09' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( '', 'FC', '任天堂', 4500, '1983-11-22' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( '', 'FC', '任天堂', 4500, '1983-12-07' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( 'JR. の算数遊び', 'FC', '任天堂', 4500, '1983-12-12' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( '', 'FC', '任天堂', 4500, '1984-01-14' );
$
PostgreSQLでは ' をエスケープするために '' と 2つ重ねて指定します
では作成した insert文を流し込みますが
psql に -f でテキストファイルを指定すれば テキストの内容を順番に実施してもらえます
$ psql -U gamer -f tvgame_insert.txt games
INSERT 0 1
〜
INSERT 0 1
$
tvgamesテーブルの完成です
実際に SQLの select構文を使って各種検索をためしてみます まずは10レコード分の表示です
$ PAGER=cat psql -U gamer games
psql (9.1.0)
"help" でヘルプを表示します.
games=> select * from tvgames limit 10;
name | plathome | company | price | release_date
------------------------------+----------+---------+-------+--------------
ドンキーコング | FC | 任天堂 | 4500 | 1983-07-15
ドンキーコングJR. | FC | 任天堂 | 4500 | 1983-07-15
ポパイ | FC | 任天堂 | 4500 | 1983-07-15
五目ならべ [連珠] | FC | 任天堂 | 4500 | 1983-08-27
麻雀 | FC | 任天堂 | 4500 | 1983-08-27
マリオブラザーズ | FC | 任天堂 | 4500 | 1983-09-09
ポパイの英語遊び | FC | 任天堂 | 4500 | 1983-11-22
ベースボール | FC | 任天堂 | 4500 | 1983-12-07
ドンキーコングJR. の算数遊び | FC | 任天堂 | 4500 | 1983-12-12
テニス | FC | 任天堂 | 4500 | 1984-01-14
(10 行)
games=>
1983年はファミコンが発売されてから爆発的にヒットする直前です
psqlは PAGER環境変数に設定されたプログラムで selectの結果を表示します
デフォルトの less が一番使い勝手がよいですが ページ送りが不要な場合など cat を指定します
次に 1995年4月1日〜5月1日 の間に発売されたソフトの一覧を表示します between構文を使います
games=> select * from tvgames where release_date between '1995-4-1' and '1995-5-1';
name | plathome | company | price | release_date
-------------------------------------------------------------+--------------------+------------------------------------------+-------+--------------
EMIT Vol.2〜命がけの旅〜 | SS | 光栄 | 8800 | 1995-04-01
EMIT Vol.3〜私にさよならを〜 | SS | 光栄 | 8800 | 1995-04-01
デイトナUSA | SS | セガ | 6800 | 1995-04-01
レディーストーカー〜過去からの挑戦〜 | SFC | タイトー | 9980 | 1995-04-01
Dの食卓 | 3DO | 三栄書房 | 8800 | 1995-04-01
蒼き伝説シュート! | GB | バンプレスト | 3980 | 1995-04-07
THE クイズ ギアファイト! | GG | セガ | 3800 | 1995-04-07
クイズ キング・オブ・ファイターズ | NG(CD) | ザウルス | 5800 | 1995-04-07
得点王3 | NG | SNK | 29800 | 1995-04-07
フォーメーションサッカー95 della セリエA | PCE(SCDR2)(AC対応) | ヒューマン | 9800 | 1995-04-07
全日本プロレス2 3・4武闘館 | SFC | 日本コンピュータシステム | 10800 | 1995-04-07
ドラえもん 友情伝説 | 3DO | 小学館 | 7800 | 1995-04-07
SD飛龍の拳外伝 | GB | カルチャーブレーン | 4700 | 1995-04-14
勝馬予想 競馬貴族EX'95 | GB | キングレコード | 6900 | 1995-04-14
ワールドヒーローズ2 | NG(CD) | ADK | 5800 | 1995-04-14
パチ夫くん パチンコランド大冒険 | PS | ココナッツジャパン | 6800 | 1995-04-14
柿木将棋 | SS | アスキー | 7800 | 1995-04-14
ぱずるんでス! | SFC | 日本物産 | 8980 | 1995-04-14
RES ARCANA | SFC | ココナッツジャパン | 9500 | 1995-04-14
EMIT Vol.1 時の迷子 | 3DO | 光栄 | 8800 | 1995-04-14
デビルズコース | 3DO | 松下電器 | 8800 | 1995-04-14
パドックノート’95 | 3DO | フジテレビジョン | 8800 | 1995-04-14
MYST | 3DO | マイクロキャビン | 7800 | 1995-04-14
Jリーグ ライブ'95 | GB | エレクトロニック・アーツ・ビクター | 5980 | 1995-04-21
カオティクス | 32X | SEGA | 7800 | 1995-04-21
餓狼伝説3 ROAD TO THE FINALVICTORY | NG | SNK | 32000 | 1995-04-21
ギャラクシーファイト UNIVERSAL WARRIORS | NG(CD) | サンソフト | 7800 | 1995-04-21
サイバーリップ | NG(CD) | SNK | 5800 | 1995-04-21
ファイヤースープレックス | NG(CD) | SNK | 5800 | 1995-04-21
ベースボールスターズプロフェッショナル | NG(CD) | SNK | 4800 | 1995-04-21
ロボアーミー | NG(CD) | SNK | 5800 | 1995-04-21
金沢将棋'95 | PS | セタ | 7900 | 1995-04-21
ママレード・ボーイ | SFC | バンダイ | 9800 | 1995-04-21
魔法陣グルグル | SFC | エニックス | 10800 | 1995-04-21
タクティカルサッカー | SFC | エレクトロニックアーツビクター | 9800 | 1995-04-21
なつきクライシスバトル | SFC | エンジェル | 10800 | 1995-04-21
真・聖刻 | SFC | ユタカ | 9800 | 1995-04-21
真SD戦国伝 大将軍列伝 | SFC | ベック | 9800 | 1995-04-21
スーパーリアル麻雀P5 パラダイス オールスター4人打ち | SFC | セタ | 9800 | 1995-04-21
リジョイス〜アレサ王国の彼方〜 | SFC | やのまん | 9900 | 1995-04-21
宮路社長のパチンコファン勝利宣言2 | SFC | POW | 9800 | 1995-04-21
スーパートランプコレクション | SFC | ボトムアップ | 8900 | 1995-04-21
紺碧の艦隊 | 3DO | 徳間書店 | 8800 | 1995-04-21
ぼのぐらし | 3DO | アミューズ/バンダイビジュアル | 8800 | 1995-04-21
ポリスノーツ パイロットディスク | 3DO | コナミ | 2980 | 1995-04-21
パズルボブル | NG(CD) | タイトー | 6800 | 1995-04-27
赤ずきんチャチャ | GB | トミー | 3900 | 1995-04-28
空想科学少年ガリバーボーイ 空想科学パズル プリッとポン | GB | バンダイ | 3980 | 1995-04-28
チキチキ天国 | GB | J・ウイング | 3900 | 1995-04-28
パチ夫くん3 | GB | ココナッツジャパン | 4800 | 1995-04-28
魔法陣グルグル 勇者とククリの大冒険 | GB | タカラ | 3980 | 1995-04-28
TEMPO Jr. | GG | セガ | 3800 | 1995-04-28
テイルスのスカイパトロール | GG | セガ | 3800 | 1995-04-28
テレビアニメスラムダンク 強豪真っ向対決! | MD | バンダイ | 8800 | 1995-04-28
トゥルーライズ | MD | アクレイムジャパン | 7800 | 1995-04-28
餓狼伝説3 ROAD TO THE FINALVICTORY | NG(CD) | SNK | 8800 | 1995-04-28
スロット勝負師 | PCE(SCDR2) | 日本物産 | 8500 | 1995-04-28
ガンナーズ ヘブン | PS | ソニー・コンピュータエンタテインメント | 5800 | 1995-04-28
ぐっすんおよよ | PS | エクシング | 6800 | 1995-04-28
ジャンピングフラッシュ!アロハ男爵ファンキー大作戦の巻 | PS | ソニー・コンピュータエンタテインメント | 5800 | 1995-04-28
ミスランド まちがい探しゲーム | PS | アルトロン | 5800 | 1995-04-28
ヴァーチャル ハイドライド | SS | セガ | 5800 | 1995-04-28
アイルトン・セナ パーソナルトーク〜Message for the future〜 | SS | セガ | 8800 | 1995-04-28
輝水晶伝説アスタル | SS | セガ | 5800 | 1995-04-28
三國志4 | SS | 光栄 | 14800 | 1995-04-28
スーパーボンバーマン3 | SFC | ハドソン | 8900 | 1995-04-28
スーパーパチンコ大戦 | SFC | バンプレスト | 6900 | 1995-04-28
牌勢麻雀 凌駕 | SFC | アスキー | 12800 | 1995-04-28
プラネットチャンプ TG3000 | SFC | ケムコ | 9500 | 1995-04-28
Jリーグエキサイトステージ'95 | SFC | エポック社 | 9800 | 1995-04-28
川のぬし釣り2 | SFC | パックインビデオ | 10800 | 1995-04-28
シミュレーションプロ野球 | SFC | ヘクト | 12800 | 1995-04-28
トゥルーライズ | SFC | アクレイムジャパン | 10900 | 1995-04-28
3次元格闘ボールズ | SFC | メディアリング | 9800 | 1995-04-28
タロットミステリー | SFC | ヴィジット | 9800 | 1995-04-28
初段位認定 初段プロ麻雀 | SFC | ギャップス | 9800 | 1995-04-28
バーチャルカメラマンPart3 | 3DO | ナグザット | 8800 | 1995-04-28
ワールドカップ スーパースタジアム | 3DO | テレビ東京/ギャガ・コミュニケーションズ | 6800 | 1995-04-28
(78 行)
games=>
NeoGeoのロムの値段の高さにびっくりしますが スーパーファミコンも1万円越えなど結構な値段です
次に group by 構文を使った機種別ソフト本数の集計です
games=> select plathome, count( name ) from tvgames group by plathome;
plathome | count
-----------------------+-------
GG | 196
SFC | 1391
PCE(SG) | 4
MCD | 110
PCE(SCDR2) | 235
NG(CD) | 99
FCD | 195
NG | 117
PCE(CDR2) | 92
32X | 18
GBC | 142
PS | 4439
SFC(NP) | 33
ARCADE CARD専用 | 12
N64 | 200
FC周辺ソフト | 9
SS | 1212
VB | 19
GB&GBC | 201
GB | 767
64DD | 7
※バーコードボーイ同梱 | 1
3DO | 215
FC | 1042
PCE(SCDR2)(AC対応) | 16
PCE | 229
MD | 416
PCE(CDR2)(S対応) | 12
(28 行)
games=>
最後に 複雑なクエリを実行して PostgreSQLのパフォーマンスを確認します
名称の先頭部分が一致することを条件にして 5作以上シリーズ化されているゲームを抜き出そうとしてます
例えば「ドラゴンクエスト」をベース名として「ドラゴンクエスト2」「ドラゴンクエスト3」…
を抜き出そうとしています
games=> select gbase.name, gelement.name, gelement.release_date, gelement.plathome, gelement.price from ( select distinct name from tvgames ) as gbase, tvgames gelement where octet_length( gbase.name ) > 3 and left( gelement.name, char_length( gbase.name ) ) = gbase.name and ( select count( name ) from tvgames gsub where gbase.name != gsub.name and left( gsub.name, char_length( gbase.name ) ) = gbase.name ) >= 4 order by gbase.name, gelement.release_date;
〜
悠久幻想曲 | 悠久幻想曲 Ensemble Vol.1 | 1998-12-10 | PS | 3800
悠久幻想曲 | 悠久幻想曲Ensemble Vol.2 | 1999-02-18 | PS | 3800
悠久幻想曲 | 悠久幻想曲 ensemble vol.2 | 1999-03-04 | SS | 3800
悠久幻想曲 | 悠久幻想曲 保存版 PerpetualCollection | 1999-10-14 | PS | 8800
悠久幻想曲 | 悠久幻想曲3 パーペチュアルブルー | 1999-12-22 | PS | 5800
遊戯王デュエルモンスターズ | 遊戯王デュエルモンスターズ | 1998-12-17 | GB | 4300
遊戯王デュエルモンスターズ | 遊戯王デュエルモンスターズ2 闇界決闘記 | 1999-07-08 | GB&GBC | 4500
遊戯王デュエルモンスターズ | 遊戯王デュエルモンスターズ3 三聖戦神降臨 | 2000-07-13 | GBC | 4500
遊戯王デュエルモンスターズ | 遊戯王デュエルモンスターズ4 最強決闘者戦記 海馬デッキ | 2000-12-07 | GBC | 4800
遊戯王デュエルモンスターズ | 遊戯王デュエルモンスターズ4 最強決闘者戦記 城之内デッキ | 2000-12-07 | GBC | 4800
遊戯王デュエルモンスターズ | 遊戯王デュエルモンスターズ4 最強決闘者戦記 遊戯デッキ | 2000-12-07 | GBC | 4800
(1749 行)
games=> \\q
$
1万レコードのテーブルを 2つ組み合わせて検索する高負荷な処理ですが
検証環境では実行時間は 61秒でした
驚くことに MySQLで同様の検索をしたときは 2分20秒だったのに比べ半分以下の時間となってます
PostgreSQLの最適化能力の高さが感じとれます
紹介は以上です PostgreSQLは機能としても高機能で
商用データベースである Oracleに決して見劣りしていないのではないでしょうか
投稿ナビゲーション