page_adsence

2011年3月31日木曜日

CSSを動的に追加したい場合にIE6でうまくいかない件

jqueryのプラグインっぽく作ってるカレンダーのやつでcssとかHTMLにいちいち差し込むの面倒なので、
JS側で後から追加しようと思っていたら、なんかIE6だけうまくいかない現象があった。

通常のブラウザはJqueryでlinkタグをheadに追加する形で問題なかったが、
IE6はそうはいかないらしい。
なので、IE6用に処理を追記する形をとった。

document.createStyleSheet(cssUrl);

この1行を追加するだけでいけました。
意外と楽にいけた。

2011年3月28日月曜日

jCalendar.jsに関して

セレクトボックスと連動型のカレンダーを探していたら、jCalendar.jsというのが見つかったので、
早速使ってみた。
このjCalendar.jsは制約として1ページにつき、1つのカレンダーしか作れないようになっている。
1ページに複数入れたい場合は改造が必要になる。その改造方法に関しては別のエントリーで解説する。

jCalendar.jsのダウンロードはここから可能です。

使い方は以下の通り。
  • 1.Jquery.jsをダウンロードしてくる。
    (対応バージョンは一応1.0.4 or 1.1.2と書かれていますが、今回1.4.3を使ってみましたけど、特に問題無かったです。)
  • 2.jCalendar.jsとjCalendar.cssを上記サイトのuseタブをクリックしたページの
    「Download jCalendar — source or compressed or svn checkout
    からダウンロード。
    今回はデザインや挙動を含め、いろいろと変更することが想定されたので、source版をダウンロードしました。
  • 3.年月日のセレクトボックスにそれぞれ「jcalendar-select-year」、「jcalendar-select-month」、「jcalendar-select-day」のクラスをつける。
  • 4.クラスを付加した年月日のセレクトボックスを<div class="jcalendar-selects">で囲む。
  • 5.それをさらに<fieldset class="jcalendar">で囲む。
  • 6.Jsで以下のコードを実行。
    $(function(){
        $('fieldset.jcalendar').jcalendar();
    });

※注意点
セレクトボックスのvalueで1桁の数字を0詰めしている場合は、カレンダーを操作してもセレクトボックスの値が書き変わらないので、注意が必要。

デフォルト状態での使い方は以上。
一応使用可能状態のHTMLも以下に記述しておく。

<fieldset class="jcalendar">
    <div class="jcalendar-selects">
        <select class="jcalendar-select-year">
            <option value="2011">2011</option>
        </select>
        <select class="jcalendar-select-month">
            <option value="3">3</option>
        </select>
        <select class="jcalendar-select-day">
            <option value="1">1</option>
        </select>
    </div>
</fieldset>

2011年3月15日火曜日

文字コードを変換する

ファイルの文字コードを調べたりするのに使う。

文字コードがわからないファイルを以下の方法で開くときちんと見れる
nkf ファイル名

オプション一覧
-j(省略可能) : JISコード(ISO-2022-JP)を出力
-e           : EUCコードを出力
-s           : Shift-JISコードを出力
-w           : UTF-8コードを出力(BOM無し)
-Lu          : unix改行形式(LF)に変換
-Lw          : windows改行形式(CRLF)に変換
-Lm          : macintosh改行形式(CR)に変換
-g(--guess)  : 自動判別の結果を表示
--overwrite  : 引数のファイルに直接上書き
--version    : バージョン情報を表示(インストール済チェック)

文字コードを確認する方法
$ nkf -g example.txt

文字コードをEUC-JPに変換する
$ nkf -e --overwrite example.txt

文字コードをUTF-8に変換する
$ nkf -e --overwrite example.txt

VMWareの仮想ディスクの拡張方法

VMWareで最初にパーティション切ってた容量がいっぱいになっってきたので、拡張してみた。
Windwosの方の空き容量が100GB以上あったので、とりあえず8GBから20GBに拡張してみた。
手順は以下の通り。


1.まず現状を確認する。
使用率が76%になっていてあまり空き容量に余裕がないことが確認できる。
確認したらVMWareを落とす。

# df -h
Filesystem          サイズ  使用  残り 使用% マウント位置
/dev/mapper/VolGroup00-LogVol00
                      7.2G  5.1G  1.7G  76% /
/dev/hda1              99M   12M   82M  13% /boot
tmpfs                 506M     0  506M   0% /dev/shm

2.VMWare-Serverに付属している「vmware-vdiskmanager.exe」を探す。
VMWareのインストールディレクトリ内にある。
通常であれば
「C:\Program Files\VMWare\VMware Server」の中にあります。

3.vmdkファイルの場所を探す。
基本的には「C:\Virtual Machines\[OS名]\[OS名].vmdk」になります。
似たような名前で「[OS名]-flat.vmdk」というファイル名があり、仮想HDD容量分のファイルがありますが、
使用するのはこちらではなく、「[OS名].vmdk」というファイルになります。

3.コマンドプロンプトを立ち上げて、「vmware-vdiskmanager.exe」があるディレクトリへ移動します。
cd C:\Program Files\VMWare\VMware Server

4.vmdkファイルを拡張します
vmware-vdiskmanager.exe -x 20GB C:\Virtual Machines\[OS名]\[OS名].vmdk

5.拡張が終わると以下のようなメッセージが出ます。
なにかWARNINGが出てますが、問題ありません。
Grow: 100% done.

The old geometry C/H/S of the disk is: 7281/16/63
The new geometry C/H/S of the disk is: 10402/16/63
Disk expansion completed successfully.

WARNING: If the virtual disk is partitioned, you must use a third-party
         utility in the virtual machine to expand the size of the
         partitions. For more information, see:
         http://www.vmware.com/support/kb/enduser/std_adp.php?p_faqid=1647

6.VMWareを立ち上げて状態を確認
容量が増えていることを確認する
# 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        1044     8281507+  8e  Linux LVM

7.パーティションを作成する
# fdisk /dev/hda
このディスクのシリンダ数は 2610 に設定されています。
間違いではないのですが、1024 を超えているため、以下の場合
に問題を生じうる事を確認しましょう:
1) ブート時に実行するソフトウェア (例. バージョンが古い LILO)
2) 別の OS のブートやパーティション作成ソフト
   (例. DOS FDISK, OS/2 FDISK)
コマンド (m でヘルプ): n
コマンドアクション
   e   拡張
   p   基本領域 (1-4)
p
領域番号 (1-4): 3
最初 シリンダ (1045-2610, default 1045):Enter
Using default value 1045
終点 シリンダ または +サイズ または +サイズM または +サイズK (1045-2610, default 2610):Enter
Using default value 2610

コマンド (m でヘルプ): t
領域番号 (1-4): 3
16進数コード (L コマンドでコードリスト表示): 8e
領域のシステムタイプを 3 から 8e (Linux LVM) に変更しました

コマンド (m でヘルプ): wq
領域テーブルは交換されました!

ioctl() を呼び出して領域テーブルを再読込みします。

警告: 領域テーブルの再読込みがエラー 16 で失敗しました: デバイスもしくはリソースがビジー状態です。
カーネルはまだ古いテーブルを使っています。
新しいテーブルは次回リブート時に使えるようになるでしょう。
ディスクを同期させます。

8.状態を再び確認
/dev/hda3が追加され、そこに空き容量が割り当てられていることを確認する
# 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        1044     8281507+  8e  Linux LVM
/dev/hda3            1045        2610    12578895   8e  Linux LVM

9.リブートもしくはpartprobeを実行する。今回はpartprobeで即時反映させる。
# partprobe

10.物理ボリュームを作成する
# pvcreate /dev/hda3
Physical volume "/dev/hda3" successfully created

11.既存のボリュームグループ(VG) に新しいパーティションを追加する
# vgextend VolGroup00 /dev/hda3
  /dev/hdc: open failed: メディアが見つかりません
  Volume group "VolGroup00" successfully extended

12.既存の論理ボリューム(LV) を追加したパーティションの分、拡張する。既存のLV は lvdisplay で確認。たぶん 「LogVol00」
# lvdisplay -C
  /dev/hdc: open failed: メディアが見つかりません
  LV       VG         Attr   LSize   Origin Snap%  Move Log Copy%  Convert
  LogVol00 VolGroup00 -wi-ao   7.38G
  LogVol01 VolGroup00 -wi-ao 512.00M

13.vgdisplay で拡張できるサイズを確認する
# vgdisplay
  /dev/hdc: open failed: メディアが見つかりません
  --- Volume group ---
  VG Name               VolGroup00
  System ID
  Format                lvm2
  Metadata Areas        2
  Metadata Sequence No  4
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                2
  Open LV               2
  Max PV                0
  Cur PV                2
  Act PV                2
  VG Size               19.84 GB
  PE Size               32.00 MB
  Total PE              635
  Alloc PE / Size       252 / 7.88 GB
  Free  PE / Size       383 / 11.97 GB
  VG UUID               pvKmW5-rMWe-K7gi-IMhr-xaBy-GPDZ-xs14kc

14.[PE Size] * [Free PE] の値が拡張できるサイズとなるので、32MB * 383 = 12256MB を拡張する。
# lvextend -L +12256MB /dev/VolGroup00/LogVol00
  /dev/hdc: open failed: メディアが見つかりません
  Extending logical volume LogVol00 to 19.34 GB
  Logical volume LogVol00 successfully resized

15.ファイルシステムを拡張する。
# resize2fs /dev/VolGroup00/LogVol00
resize2fs 1.39 (29-May-2006)
Filesystem at /dev/VolGroup00/LogVol00 is mounted on /; on-line resizing required
Performing an on-line resize of /dev/VolGroup00/LogVol00 to 5070848 (4k) blocks.
The filesystem on /dev/VolGroup00/LogVol00 is now 5070848 blocks long.

16.容量が増えていることを確認する
# df -h
Filesystem          サイズ  使用  残り 使用% マウント位置
/dev/mapper/VolGroup00-LogVol00
                       19G  5.1G   13G  29% /
/dev/hda1              99M   12M   82M  13% /boot
tmpfs                 506M     0  506M   0% /dev/shm

キャッシュフォルダ等のフォルダをsvn管理下から除外する方法

なんか毎回ハマってる気がするのでメモ。
svnで編集する際に使用するエディタにviを指定(もともと指定している場合は不要)
$ export SVN_EDITOR="vi"

カレントディレクトリを開き、管理外にしたいディレクトリ名を記載する。
このコマンドを実行するとviが開く
$ svn propedit svn:ignore .

開いたviに管理外にしたいディレクトリ名を記載する。
例)カレントディレクトリにあるcacheディレクトリを除外したい場合
cache

で、保存して閉じる。
ちなみに、一度svn管理下に置いてしまった場合はsvn deleteで削除し、
svn管理外の状態にした状態で除外する必要がある。

2011年3月11日金曜日

MySQLの高速化を図った時のログ

今取り組んでいる仕事で、集計データを格納しているテーブルが30個近くあり、それを一つのViewにまとめてしまおうと思ったのですが、調べてみていろいろとわかったのでメモ。

集約するような場合にビューを使用すると致命的に遅くなってしまう。
なぜかというと、結局ビューも実体をもたないただのクエリだから。
そんなビューに対して集約するようなクエリを投げると以下のような流れで集約の作業が行われる。

元テーブルでそれぞれ集約→その結果を結合してさらに集約

ということで、ビューで集約はできない。
じゃあどうするか。

次に思い浮かんだのは全テーブルを1つのテーブルにしてしまうこと。
しかしそれでは素材数によっては1日でかなりの量のレコードが追加されていくことになる。
MyISAMの場合、1テーブルの最大サイズは4GBまでになっており、
何年も集約結果が蓄積されていくことを考えると実現することは難しい。

となるとどういった方法がいいのか…。
結局各テーブルからデータを取得する際にインデックスを適切に貼り、
ひとつひとつのクエリの実行速度を上げていくしかないと思う。
ひとつひとつのクエリの実行速度が上がれば、ビューを作成してもかかる時間は短縮されるはず。

2011年3月9日水曜日

DBDesigner4からMySQLサーバに接続する方法

DBDesigner4から自分のWindowsに入れてあるVMWare上のMySQLサーバに接続しようとした時のログ。

MySQLに接続しようとすると
「 dbExpress Error Invalid Username/password」
というエラーが発生して繋がらなかった。
で、MySQLを見てみたら、外部ホストから接続できるようにしてなかった。

MySQLにログインして、mysqlのDBを選択
GRANT ALL PRIVILEGES ON *.* to ユーザー名@"ホストIP" IDENTIFIED BY 'パスワード' WITH GRANT OPTION;

で、もう一回試してみたら再び同じエラーが…。
ググってみると、いろいろ引っかかってきた。

MySQL4.1以降の認証方式の違いで、MySQLに接続時に必ず
「 dbExpress Error Invalid Username/password」
といったエラーが発生する。
これは
「ユーザー名かパスワードが違う」
というエラーで、認証情報があっていても繋がらない。

これを回避するには以下のSQLを実行する必要がある。
SET PASSWORD FOR 'ユーザー'@'ホスト' = OLD_PASSWORD('新パスワード');
例)
SET PASSWORD FOR 'root'@'Windows上のVMnet8のIP' = OLD_PASSWORD('新パスワード');

で、もう一回接続。
キターーー。

とりあえず、これで問題ないみたいです。
が、PHP5.3以降はこの設定が使えないみたいなので、
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('新パスワード');
とする必要があるみたいです。

非SSLページからSSLページへリダイレクト

非SSLページからSSLにリダイレクトさせたい場合は、ssl.confに記載されている部分には触れずに、
httpd.conf内のバーチャルホストの設定を変更する。

<VirtualHost *:80>
    ServerName ~~~
    ServerAdmin ~~~
    DocumentRoot ~~~
    ErrorLog ~~~
    CustomLog ~~~
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteCond %{SERVER_PORT} !^443$
        RewriteRule (.*) https://%{HTTP_HOST}$1 [L,R]
    </IfModule>
</VirtualHost>

赤文字で記載されている部分を追記し、apacheの設定をリロードすればリダイレクトされるようになる。
この設定はポート443以外でアクセスされた全てのリクエストをSSLページにリダイレクトする。
という設定である。
例)
http://test.co.jp/test.phpにアクセスがあった場合に、https://test.co.jp/test.phpにリダイレクトされる。

2011年3月8日火曜日

mod_rewriteを使おうとしたらOSデフォルトのWebページになってしまった

.htaccessを使って新集計ツールサーバに来るアクセスを全てメンテナンスページにリダイレクトさせる設定をしようとした。
とりあえずhttpd.confの中のAllowOverrideがNoneになっていたので、そこをAllに修正して保存しreload
<Directory />
    Options FollowSymLinks
    AllowOverride None → All
</Directory>


で、.htaccessに以下のように記述してページにアクセス。
<Directory ~~~>
ErrorDocument 503 /html/maintenance.html

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST_URI} !=/html/maintenance.html
  RewriteCond %{REQUEST_URI} !=/images/construction.jpg
  RewriteRule ^.*$ - [R=503,L]
</IfModule>
</Directory>


すると、CentOSデフォルトのWebページが表示されてしまった。
エラーログを見ると以下のようなエラーが出ていた。
Options FollowSymLinks or SymLinksIfOwnerMatch is off which implies that RewriteRule directive is forbidden: ディレクトリパス


mod_rewriteを使うディレクトリでは「Options FollowSymLinks」が必要だったので、
そこを.htaccessに追加したら問題なく動いた。
Options FollowSymLinks
ErrorDocument 503 /html/maintenance.html

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST_URI} !=/html/maintenance.html
  RewriteCond %{REQUEST_URI} !=/images/construction.jpg
  RewriteRule ^.*$ - [R=503,L]
</IfModule>

2011年3月7日月曜日

mysqlの世代バックアップとリストアに関して

mysqlの世代バックアップは以下の通り。
cronの実行時間に関しては適宜変更する。
以下の記述で4日間分のバックアップが残る

* * * * * mysqldump -u ユーザー名 -p パスワード データベース名 --default-character-set=文字コード | gzip > db/dump_`date +"\%Y\%m\%d_\%H"`.sql.gz
* * * * * find db/ -type f -name "dump_*.tar.gz" -mtime +3 -daystart | xargs rm

バックアップからデータベースにリストアする方法は以下の通り。
zcat ダンプファイル名.gz | mysql -u ユーザー名 -p パスワード データベース名

こんな感じでリストアできるみたい。
zcatコマンドとかつかったこと無かったけど、こんな風に使うのか。

2011年3月4日金曜日

PHPで数字かどうかを判定する

今まで数字かどうかは正規表現使ってましたけど、実はこんな関数があって、こっちの方が早いらしい。
今後はこれを使っていこうと思う。

ctype_digit

PHPの三項演算子のネストは使わない方がいい

何回か三項演算子をネストさせようとして、思い通りにいかなかくてあきらめていたけど、
PHPの仕様だったみたいです。
PHPで三項演算子のネストは駄目だ。

2011年3月2日水曜日

MySQLで「Got error 28 from...」と出るときの対処法

MySQLでmysqldumpを取ろうと思ったら、dumpファイル自体は生成されているが、明らかに容量が少ないファイルができていた。
で、出てくるエラーメッセージが「Got error 28 from storage engine」

ググってみたら、ディスクの容量が足りないってことが原因だったみたい。
dfコマンドで確かめてみたら確かに100%使い切っていた…。
VMWareのディスクを拡張したことで解決!
VMWareのディスク拡張方法はこちらに記載しました。