tohokuaikiのチラシの裏

技術的ネタとか。

PostgreSQLのセットアップでいつもハマル僕のための覚書

PostgreSQLには苦手意識を持っている。MySQLならこんな簡単なのに・・・・。と。 単に使う機会が少ないので覚えないだけだったりするのだけど。。。

Roleの作成

MySQLのユーザーに対応するのがPostgreSQLのRoleの概念。

とりあえず、postgresのスーパーユーザーでpsqlコマンドでログインした後には一般ユーザー的なそれを作っておく。

postgres=# CREATE ROLE foo WITH LOGIN PASSWORD 'foo_password'

pg_hba.conf をいじってログインできるようにする。

ホスト別のアクセスコントロール。ここで、peerとなっているとPostgresのロールとUnixログインのアカウントが結び付けられる。 つまり、先ほど作ったpostgresのロールfooでログインしたい場合、

psql -U foo -W

で求められるプロンプトに入力するのはた際に先ほどのfoo_passwordではなく、Unixログインアカウントfooのパスワードなのである。

ということで、pg_hba.confを下記のように変更。md5というのは、create roleで設定したパスワードにするということ。

local   all             all                                     md5
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5

psql -Uでログインできない

MySQLmysqlコマンドのノリでログインしようとするとログインできない。

$ psql -U foo -W

とすると、パスワードがあっててもログイン後に即座に「foo」というデータベースにつなげようとするのでこのデータベースがありませんエラーでログアウトされてしまう。そこで、必ずあるデータベースであるpostgresに接続指定する。

$ psql -U foo -W -d postgres

で何とかログインする。

データベースを作るにはテンプレートが必要

create databaseしようとしたらエラーが出た。

No relations found.
postgres=# create database  "xxx_development" ENCODING = 'unicode'
postgres-# ;
ERROR:  new encoding (UTF8) is incompatible with the encoding of the template database (SQL_ASCII)
HINT:  Use the same encoding as in the template database, or use template0 as template.

...templateってなんだっけ・・・と思って調べる・・・

blog.netandfield.com

PostgreSQL の createdb は、実際には template1 という空の DB をコピーして新しい DB を作成する。
で、この template1 という DB には initdb した時に指定した文字コード情報が登録されているのだ。
だから、「UTF-8 の文字コードを使う DB をコピーして、EUC-JP の文字コードを使う DB は作れんでぇ」と怒られてる。

じゃあ、どうすればいいか?・・・だが、エラーメッセージに HINT として示されているように、template0 を使えば良いわけね。
template0 は、文字コードの情報を持っていない、本当にピュアな DB なので、他の文字コードの DB の元ネタになるってわけだね。

ということで、

postgres=# create database  "xxx_development" ENCODING = 'unicode' --template=template0

として作成完了。

template0がなんかLATIN1になってるからやっぱりUTF8で作れない

Ubuntu16のまんまその状態だとこうなってた。

postgres=# \l
                                      List of databases
            Name             |  Owner   | Encoding | Collate | Ctype |   Access privileges
-----------------------------+----------+----------+---------+-------+-----------------------
 enju_leaf_junoe_development | junoe    | UTF8     | C       | C     |
 enju_leaf_junoe_test        | junoe    | UTF8     | C       | C     |
 postgres                    | postgres | LATIN1   | en_US   | en_US |
 template0                   | postgres | LATIN1   | en_US   | en_US | =c/postgres          +
                             |          |          |         |       | postgres=CTc/postgres
 template1                   | postgres | LATIN1   | en_US   | en_US | =c/postgres          +
                             |          |          |         |       | postgres=CTc/postgres

template2をUTF8で作る。(これがベストなのかは知らない)

postgres@local:~$ createdb template2 --locale=C --encoding=UTF8 --template=template0

そのあと、このtemplate2を基にしてDBを作成する。

Railsのバージョンアップとgemのバージョンアップをする

UbuntuのOSアップデートに合わせてRailsもアップデート

1つ前のエントリでUbuntuをアップデートしたので

railをアップデートしたいのだけど、そのRubyのパッケージマネージャであるgemをアップデート

gemをアップデートするためには、rubygems-updateというgemをインストールして使用する。

root@localhost:~# gem install rubygems-update
Fetching: rubygems-update-2.6.6.gem (100%)
Successfully installed rubygems-update-2.6.6
Parsing documentation for rubygems-update-2.6.6
Installing ri documentation for rubygems-update-2.6.6
Done installing documentation for rubygems-update after 49 seconds
1 gem installed

インストールできたので、gem自体をアップデート

root@localhost:~# gem -v
2.5.1
root@localhost:~# update_rubygems
RubyGems 2.6.6 installed
Parsing documentation for rubygems-2.6.6
Installing ri documentation for rubygems-2.6.6

..........
このあたり長々とチェンジログやら表示
..........

root@localhost:~# gem -v
2.6.6

ということで、2.6.6になった。

railsのアップデート

root@localhost:~# gem update rails
Updating installed gems
Updating rails
.....(略


root@localhost:~# rails -v
Rails 5.0.0

Ubuntu server を14から16にアップグレードしてPostgresを9.5にする

Postgresqlの9.5を使いたくなったのだけど、Ubuntu14だと9.3なのでUbuntu16にアップデートしてPostgresを9.5にしようということに。

あ、UbuntuはもちろんUbuntuサーバーです。

とりあえず、Ubuntuのアップデート

死ぬほど簡単だった。

$ sudo do-release-upgrade -d

これだけ。色々とY/Nはあったけど。

Postgres9.5のインストールと起動

とりあえず、

$ sudo apt-get install postgresql-9.5
$ sudo apt-get install postgresql-client-9.5

ほんで、

$ sudo service postgresql stop
$ sudo service postgresql start

とすると、9.3と9.5が同時に立ち上がる。ポートが違う。

postgres@localhost:~$ psql -p 5432
psql (9.5.3, server 9.3.13)
Type "help" for help.

postgres=# select version();
                                                   version
--------------------------------------------------------------------------------------------------------------
 PostgreSQL 9.3.13 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4, 64-bit
(1 row)

postgres=# \q
postgres@localhost:~$ psql -p 5433
psql (9.5.3)
Type "help" for help.

postgres=# select version();
                                                 version
----------------------------------------------------------------------------------------------------------
 PostgreSQL 9.5.3 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 5.3.1-14ubuntu2) 5.3.1 20160413, 64-bit
(1 row)

こんな感じ。

9.3は普通に使わないので

Ubuntuの機能として、Postgresのバージョン違いとかクラスタにして管理するとかがあるらしい。

lets.postgresql.jp

この同居機能もその1つなので、OFFにしてやる。

$ emacs /etc/postgresql/9.3/main/start.conf
manual

として、通常のinitでは起動しなくする。

disabledとすると通常のinitどころかUbuntuのPostgres制御コマンドのpg_ctlclusterでも使えない。ただし、pg_ctlclusterではなく通常のPostgresコマンドを使えば問題なく起動できる。*1

ついでにポートを通常値にしておく。

9.3が5432ポートを使ってたので、9.5がそれを使うようにする。 /etc/postgresql/9.5/main/postgresql.conf

port = 5432

/etc/postgresql/9.3/main/postgresql.conf

port = 5433

とする。

# /etc/init.d/postgresql restart
# su - postgres -c "psql"
psql (9.5.3)
Type "help" for help.

postgres=# select version();
                                                 version
----------------------------------------------------------------------------------------------------------
 PostgreSQL 9.5.3 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 5.3.1-14ubuntu2) 5.3.1 20160413, 64-bit
(1 row)

*1:通常のコマンドを使うというのはかなりのメンテナンスモードなので誤操作防止のための設定値。

auでテザリングするとHTTPのIPアドレスとSSHのIPアドレスが変わってしまって困る件

何で困るかというと、iptablesでWEBからアクセスしたIPアドレスを一時的にiptablesSSH許可リストに入れるようなバッチを組んでいて、それがうまく動作しないからである。

misc/add_ip_tables at master · tohokuaiki/misc · GitHub

auの公式情報

www.au.kddi.com

を見ると、現時点の使用IP帯域を教えてくれるのだけどこれを一括OKにするのはガバガバすぎる。

ということで、上記のスクリプトを80番ポートではなくほかのポートで提供することにした。

apacheでバーチャルホストを8887番で立てる

ports.confで、8887(一例)をListenし、バーチャルホストを立てる。

Listen 8887
NameVirtualHost foo.example.com:8887
<VirtualHost foo.example.com:8887>
        ServerName foo.example.com
        DocumentRoot /xxxxx/public_html/
</VirtualHost>

という感じ。

80番ポートでなければProxyされないで同じIPで接続していくのでこれでOK.

Wgetでサイトを丸ごと保存する際のオプション

こんな感じかな?

$wget -r -E -p -k --restrict-file-names=windows http://example.jp/
オプション 説明
-r 再帰取得
-E HTML拡張子で保存
-p jsやcss、画像なども保存
-k jsやcss、画像などを相対パスに書き換える
--restrict-file-names=windows Windowsで使えるようなファイル名にして保存