MySQLのクエリキャッシュ

クエリキャッシュの設定

my.cnf

[mysqld]
query_cache_size=64M
query_cache_type=2

query_cache_type には、以下のいずれかを指定できる。
0: (OFF) キャッシュを行わない、または キャッシュした結果の読み出しを行わない。
1: (ON) SELECT SQL_NO_CACHE で始まるステートメント以外のキャッシュ。
2: (DEMAND) SELECT SQL_CACHE で始まるステートメントだけのキャッシュ。

クエリキャッシュのステータスを確認

mysql> show status like 'Qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 1        | 
| Qcache_free_memory      | 66674696 | 
| Qcache_hits             | 8        | 
| Qcache_inserts          | 41       | 
| Qcache_lowmem_prunes    | 0        | 
| Qcache_not_cached       | 1145     | 
| Qcache_queries_in_cache | 41       | 
| Qcache_total_blocks     | 88       | 
+-------------------------+----------+
8 rows in set (0.00 sec)

クエリキャッシュのデフラグメント

mysql> FLUSH QUERY CACHE;

クエリキャッシュからクエリ結果を削除

mysql> RESET QUERY CACHE;

MySQL :: MySQL 5.1 リファレンスマニュアル :: 4.13 MySQL クエリ キャッシュ

Rails3のActionMailerでOpenSSL::SSL::SSLError (hostname was not match with the server certificate)

Rails3でメールを送信したところ、送信できなかった。
ActionMailerの設定は、
config/initializers/02_action_mailer.rb

ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
  :address        => "mail.example.com",
  :port           => "587",
  :domain         => "example.com",
  :user_name      => "username",
  :password       => "password",
  :authentication => :cram_md5
}

のようにしている。
同じ設定で、Rails2では送信できている。

原因

ActionMailer::Base.raise_delivery_errors = true

を追加して実行したところ、

OpenSSL::SSL::SSLError (hostname was not match with the server certificate)

となり、SSL証明書の検証で例外が発生しているらしいことが分かった。
また、メールサーバのログでも、

connect from xxxxx
setting up TLS connection from xxxxx
TLS connection established from xxxxx
lost connection after STARTTLS from xxxxx
disconnect from xxxxx

という状態だった。
このメールサーバはテスト用のpostfixで、
smtpd_tls_security_level = may
にしており、
smtpd_tls_cert_file、smtpd_tls_key_file には、自己署名証明書を設定していた。
Rails3では、STARTTLSがデフォルトで有効になっているためTLSで接続しようとするが、このメールサーバの証明書がテスト用の自己証明書だったので検証に失敗していたのが原因らしい。

解決方法

証明書を正当なものにすればよいと思われるが、テスト環境なのでとりあえず今は自己署名証明書を使いたい。
そのためには、ActionMailer::Base.smtp_settingsの設定で、STARTTLSを無効にするか証明書の検証を無効にする。

ActionMailer::Base.smtp_settings = {
  :address        => "mail.example.com",
  :port           => "587",
  :domain         => "example.com",
  :user_name      => "username",
  :password       => "password",
  :authentication => :cram_md5,
  :enable_starttls_auto => true,  # STARTTLSを無効にする場合はfalseにする
  :openssl_verify_mode => 'none'  # STARTTLSを有効にしつつ、不正な証明書もOKにしたい場合は、証明書の検証を無効にする
}

証明書の検証を無効にするのは本当はよくないけど、テスト環境等で自己署名証明書でもOKにしたい場合は、とりあえず上記のようにすれば、TLSでメールが送信できます。
OpenWebOps
email - Postfix & Rails 3.0 ActionMailer: lost connection after STARTTLS - Stack Overflow

MacのターミナルでのEmacsのメタキー

MacのターミナルでEmacsを使う場合に、デフォルトだとメタキーとしてエスケープキーしか使えないので不便だったが、ターミナルの環境設定→キーボードで、「メタキーとして option キーを使用」にチェックを入れると、optionキーをメタキーとして使用できた。
[mac][emacs] Terminal上でemacsのメタキーを使う方法 - goinger的日記

/etc/fstabの記述ミスで起動できなくなった場合

fdiskでパーティションを削除した後、/etc/fstab に削除したパーティションのエントリを残したままサーバを再起動したところ、起動時のファイルシステムチェックでエラーになり、起動しなくなってしまった。
その対処方法。

  1. エラー画面でrootパスワードを入力してメンテナンスモードに入る。
  2. / が読み取り専用モードでマウントされているため、書き込み可能なようにマウントし直す。これをしないと、fstabを編集できない。

    # mount -o remount,rw /
    
  3. fstabの不要エントリ(実際には削除されているが、エントリに残っているディスクパーティション)を削除。

    # nano /etc/fstab
    
  4. システムを再起動。
    # shutdown -r now
    

/etc/fstabの記述ミスでOSブート不能 - shibainu55日記

さくらのクラウドでパーティションの移動

さくらのクラウドで、/homeディレクトリを追加ディスク内のパーティションに移動してみた。
まず、さくらのクラウドのコントロールパネルでディスクを追加してサーバに接続しておく。
下記では、追加したディスクは、/dev/hdb として認識されています。
移行の手順は以下の通り。

fdiskでパーティションを作成する

# fdisk /dev/hdb
このディスクのシリンダ数は 2610 に設定されています。
間違いではないのですが、1024 を超えているため、以下の場合
に問題を生じうる事を確認しましょう:
1) ブート時に実行するソフトウェア (例. バージョンが古い LILO)
2) 別の OS のブートやパーティション作成ソフト
   (例. DOS FDISK, OS/2 FDISK)
コマンド (m でヘルプ): n
コマンドアクション
   e   拡張
   p   基本領域 (1-4)
p
領域番号 (1-4): 1
最初 シリンダ (1-2610, default 1): 
Using default value 1
終点 シリンダ または +サイズ または +サイズM または +サイズK (1-2610, default 2610): 
Using default value 2610
コマンド (m でヘルプ): p
Disk /dev/hdb: 21.4 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = シリンダ数 of 16065 * 512 = 8225280 bytes
デバイス Boot      Start         End      Blocks   Id  System
/dev/hdb1               1        2610    20964793+  83  Linux
コマンド (m でヘルプ): w
領域テーブルは交換されました!
ioctl() を呼び出して領域テーブルを再読込みします。
警告: 領域テーブルの再読込みがエラー 16 で失敗しました: デバイスもしくはリソースがビジー状態です。
カーネルはまだ古いテーブルを使っています。
新しいテーブルは次回リブート時に使えるようになるでしょう。
ディスクを同期させます。

ここでいったんリブートする。

作成したパーティションにファイルシステムを作成する

# mkfs -t ext3 /dev/hdb1 
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
2621440 inodes, 5241198 blocks
262059 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
160 block groups
32768 blocks per group, 32768 fragments per group
16384 inodes per group
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
	4096000
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 20 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

/mnt での新規ファイル・システムのマウント

いったん新しいディレクトリにマウントする。
ここでは、/mnt/newpart というディレクトリにマウントした。

# mkdir /mnt/newpart
# mount /dev/hdb1 /mnt/newpart

このマウントは一時的なものなので、/etc/fstabには記述しない。

ファイルのコピー

ここからは、さくらのクラウドのコントロールパネルのコンソールで操作する。
まず、安全にファイルをコピーするために、シングルユーザモードにする。

# telinit 1

ファイルをコピーする。

# cd /home
# cp -ax * /mnt/newpart/

マウントポイントの変更

# mv /home /home.old
# mkdir /home
# mount /dev/hdb1 /home

exitでシングルユーザモードを抜ける。

# exit

/etc/fstabの編集。

# nano /etc/fstab

/etc/fstab に以下の行を追加。

/dev/hdb1               /home                   ext3    defaults        1 2

再起動

再起動すると、/dev/hdb1 が /home のみにマウントされた状態になる。
確認。

$ df -h
Filesystem          サイズ  使用  残り 使用% マウント位置
/dev/hda2              18G  8.8G  7.8G  53% /
/dev/hda1              99M   18M   76M  20% /boot
tmpfs                1006M     0 1006M   0% /dev/shm
/dev/hdb1              20G  5.6G   14G  30% /home

元に戻す場合

問題があって元に戻す場合は、さくらのクラウドのコンソールでシングルユーザモードにして、/homeをumount後、/homeを削除、/home.oldを/homeにリネームすればよい。あと、/etc/fstab から/homeのマウントのエントリを削除するのを忘れずに。
/homeディレクトリをumountするとき、device is busy となってアンマウントできない場合は、

# umount -l /home

でアンマウントする。
パーティションの活用: /home の移動編
ITmedia エンタープライズ : Linux Tips「「/home/」などのディレクトリを,ほかのドライブ(パーティション)に移動したい」
マウントポイントの移動 - Linux on Titan700

さくらのクラウドでディスクを追加

さくらのクラウドでディスクを追加、サーバ(CentOS 5.7)に接続、マウントして使えるようにした。

ディスクの追加

まず、さくらのクラウドのコントロールパネルで、ディスクを追加して、サーバに接続しておく。

パーティションの作成

# fdisk -l
Disk /dev/hda: 21.4 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = シリンダ数 of 16065 * 512 = 8225280 bytes
デバイス Boot      Start         End      Blocks   Id  System
/dev/hda1   *           1          13      104391   83  Linux
/dev/hda2              14        2355    18812115   83  Linux
/dev/hda3            2356        2610     2048287+  82  Linux swap / Solaris
Disk /dev/hdb: 21.4 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = シリンダ数 of 16065 * 512 = 8225280 bytes
ディスク /dev/hdb は正常な領域テーブルを含んでいません

/dev/hdb が追加されているのが分かる。
fdiskの引数に追加したディスクのデバイスファイルのパス(/dev/hdb)を指定して実行。

# fdisk /dev/hdb
デバイスは正常な DOS 領域テーブルも、Sun, SGI や OSF ディスクラベルも
含んでいません
新たに DOS ディスクラベルを作成します。あなたが書き込みを決定するまで、変更は
メモリ内だけに残します。その後はもちろん以前の内容は修復不可能になります。
このディスクのシリンダ数は 2610 に設定されています。
間違いではないのですが、1024 を超えているため、以下の場合
に問題を生じうる事を確認しましょう:
1) ブート時に実行するソフトウェア (例. バージョンが古い LILO)
2) 別の OS のブートやパーティション作成ソフト
   (例. DOS FDISK, OS/2 FDISK)
警告: 領域テーブル 4 の不正なフラグ 0x0000 は w(書き込み)によって
正常になります
コマンド (m でヘルプ):

この警告は気にする必要はない。
続いてパーティションを作成する。
まず p コマンドで現在設定されているパーティションを確認。

コマンド (m でヘルプ): p
Disk /dev/hdb: 21.4 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = シリンダ数 of 16065 * 512 = 8225280 bytes
デバイス Boot      Start         End      Blocks   Id  System

パーティションはまだない。
n コマンドでパーティションを作成する。
基本領域を作成するので、コマンドアクションは「p」を指定。
領域番号は「1」を指定。
最初シリンダと終了シリンダはデフォルトでOK。

コマンド (m でヘルプ): n
コマンドアクション
   e   拡張
   p   基本領域 (1-4)
p
領域番号 (1-4): 1
最初 シリンダ (1-2610, default 1): 
Using default value 1
終点 シリンダ または +サイズ または +サイズM または +サイズK (1-2610, default 2610): 
Using default value 2610

p コマンドでパーティションを確認。

コマンド (m でヘルプ): p
Disk /dev/hdb: 21.4 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = シリンダ数 of 16065 * 512 = 8225280 bytes
デバイス Boot      Start         End      Blocks   Id  System
/dev/hdb1               1        2610    20964793+  83  Linux

w コマンドで書き込む。

コマンド (m でヘルプ): w
領域テーブルは交換されました!
ioctl() を呼び出して領域テーブルを再読込みします。
警告: 領域テーブルの再読込みがエラー 16 で失敗しました: デバイスもしくはリソースがビジー状態です。
カーネルはまだ古いテーブルを使っています。
新しいテーブルは次回リブート時に使えるようになるでしょう。
ディスクを同期させます。

警告が出たので、ここでいったんリブートした。

パーティションをフォーマットする

# mkfs -t ext3 /dev/hdb1
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
2621440 inodes, 5241198 blocks
262059 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
160 block groups
32768 blocks per group, 32768 fragments per group
16384 inodes per group
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
	4096000
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 21 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

必要に応じて、tune2fsでfsckのタイミングを設定する。
tune2fs

マウント

マウントポイントを作成する。

# mkdir /backup

マウントを実行。

# mount /dev/hdb1 /backup

正しくマウントされているかを確認。

# mount
/dev/hda2 on / type ext3 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/hda1 on /boot type ext3 (rw)
tmpfs on /dev/shm type tmpfs (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
/dev/hdb1 on /backup type ext3 (rw)

システム起動時に自動マウントするようにするため、/etc/fstabに以下を追加する。

/dev/hdb1               /backup                 ext3    defaults        1 2

※万一、fstabの記述にミスがあった場合、ブートできなくなってしまう。
その場合は、コントロールパネルのコンソールでメンテナンスモードに入り、fstabを修正して、リブートする。
手順は以下を参照。
/etc/fstabの記述ミスで起動できなくなった場合

参考:
memomemo : さくらのクラウド ディスクの追加 on CentOS5

Cの宣言の読み方

Cの型宣言は読みにくい。
「例解UNIXプログラミング教室」(冨永和人、権藤 克彦 ピアソンエデュケーション)の説明が分かりやすい。

  1. 最左の識別子(関数名や変数名など)に注目する。それ以外の識別子は引数の名前なので無視する。
  2. 下記の優先度に従い、その識別子から外側に向かいカッコをつける。左側の*よりも先に、右側の()や[]にカッコをつけるのがポイント。
  3. 日本語なら外側から、英語なら内側から読む。

優先度(上ほど強く結合)

記号 説明
() 宣言のグループ化
[], () 配列、関数引数
* ポインタ
その他 intなど

例: signalの型

void (*signal (int sig, void (*handler)(int)))(int);

  1. 最左の識別子はsignal。(sigとhandlerは引数)。
  2. signalからカッコをつける。

    1. *より()の方が強いので、signal (int sig, void (*handler)(int)) をカッコで囲む。
    2. 一番左のvoidより一番右の (int) の方が強いので、一番左の void 以外をカッコで囲む。
    3. 結果はこうなる。
      void ((*(signal (int sig, void (*handler)(int))))(int));
  3. 外側からカッコを外しながら読む。

    1. void ⚫; ⚫はvoid
    2. void (⚫)(int); ⚫はvoidを返す関数(引数はint
    3. void (* ⚫)(int); ⚫はvoidを返す関数(引数はint)へのポインタ
    4. void (*signal(⚫))(int); signalはvoidを返す関数(引数はint)へのポインタを返す関数(引数は⚫)
    5. void (*signal(int sig, void (*handler)(int)))(int); signalはvoidを返す関数(引数はint)へのポインタを返す関数(引数はintとvoidを返す関数(引数はint)