スタッフブログ

  • 最新配信
  • RSS

XOOPS Cubeサタデーラボのfacebookページあります

Ryuji : XOOPS » 総合的な情報 2011/7/19 11:05

Blogger's Avatar

告知してませんでしたが、XOOPS Cubeサタデーラボのfacebookページあります

熱心な参加者の皆さんにささえられて、今度の土曜(2011/07/23)で第17回目になるXOOPS Cubeサタデーラボですが、facebookページがあるのご存知ですか?

けっこう前につくってたんですが、ryus.co.jp でお知らせするのをすっかり忘れてました(^^;

■Facebookでサタラボ最新情報を入手しませんか?


ちょっと今回は実験的に参加申込もfacebook ページからできるようにしてみました。

# 今回は更に実験的に、ATNDでも受け付けてます。

どこでもお好みの方法で申込していただければと思ったんですが、あちこちで申込できるとかえってどこで申込したらいいか迷いますかね?

モジュールを一括アップデートしてくれる超便利なプリロード:RapidModuleUpdate

suin : XOOPS » プリロード 2011/3/1 12:49

Blogger's Avatar

XOOPS Cubeにありそうでなかった機能の一つが、「モジュール一括アップデート」機能です。 モジュールのアップデートを行うとなると、個々のモジュールのアップデートページで ひとつひとつ対応していくことになります。 決まった作業なのに、手作業とは手間ですね。 そこで、モジュールアップデート作業を自動で処理できるようなプラグイン(プリロード)を作りました。

RapidModuleUpdateは、モジュール一括アップデート機能をモジュール管理に追加するプラグイン(プリロード)です。 まずは、そのでも動画をごらんください。30秒で終わります。

このように、RapidModuleUpdateは複数のモジュールアップデート作業を自動化し、なんとも手間いらずです。

インストールの方法も簡単です。FTPでRapidModuleUpdate.class.phpを/preloadフォルダに置くだけで完了です。 あとは、管理者権限でログインして、「モジュール管理」を開いてみてください。 上の動画にあったような一括アップデートのチェックボックスが出ているはずです。

RapidModuleUpdateダウンロード

CentOSのPHP5.1をPHP5.2にアップグレードする方法

suin : PHP 2011/2/22 16:03

Blogger's Avatar

CentOSのPHPのデフォルトバージョンは5.1です。なので、PHP5.2にアップデートすることがよくあるので備忘録として手順をまとめておきます。

手順

とりあえずサーバを停止

sudo /etc/init.d/httpd stop
sudo /etc/init.d/mysqld stop

リポジトリを追加する。

sudo vi /etc/yum.repos.d/utterramblings.repo
[utterramblings]
name=Jason's Utter Ramblings Repo
baseurl=http://www.jasonlitka.com/media/EL$releasever/$basearch/
enabled=1
gpgcheck=1
gpgkey=http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka

アップデートをかける。

sudo yum update php -y

実際はここではまりました。ハマった詳細は後述。

リポジトリをOFFにする。enabledを0に書き換えます。

sudo vi /etc/yum.repos.d/utterramblings.repo
[utterramblings]
name=Jason's Utter Ramblings Repo
baseurl=http://www.jasonlitka.com/media/EL$releasever/$basearch/
enabled=0
gpgcheck=1
gpgkey=http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka

サーバを起動する。

sudo /etc/init.d/httpd start
sudo /etc/init.d/mysqld start

はまったところ

yum update phpで次のようなエラーが出てアップデートできずはまりました。

$ sudo yum update php
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * addons: ftp.yz.yamagata-u.ac.jp
 * base: ftp.yz.yamagata-u.ac.jp
 * extras: ftp.yz.yamagata-u.ac.jp
 * updates: ftp.yz.yamagata-u.ac.jp
Excluding Packages from CentOS-5 - Base
Finished
Setting up Update Process
Resolving Dependencies
--> Running transaction check
--> Processing Dependency: php = 5.1.6-27.el5_5.3 for package: php-devel
---> Package php.x86_64 0:5.2.16-jason.1 set to be updated
--> Processing Dependency: php-common = 5.2.16-jason.1 for package: php
--> Processing Dependency: php-cli = 5.2.16-jason.1 for package: php
--> Running transaction check
---> Package php-cli.x86_64 0:5.2.16-jason.1 set to be updated
--> Processing Dependency: php-common = 5.1.6-27.el5_5.3 for package: php-pdo
--> Processing Dependency: php-common = 5.1.6-27.el5_5.3 for package: php-ldap
--> Processing Dependency: php-common = 5.1.6-27.el5_5.3 for package: php-mbstring
--> Processing Dependency: php-common = 5.1.6-27.el5_5.3 for package: php-gd
--> Processing Dependency: php-common = 5.1.6-27.el5_5.3 for package: php-mysql
---> Package php-common.x86_64 0:5.2.16-jason.1 set to be updated
---> Package php-devel.x86_64 0:5.2.16-jason.1 set to be updated
--> Running transaction check
---> Package php-gd.x86_64 0:5.2.16-jason.1 set to be updated
---> Package php-ldap.x86_64 0:5.2.16-jason.1 set to be updated
---> Package php-mbstring.x86_64 0:5.2.16-jason.1 set to be updated
---> Package php-mysql.x86_64 0:5.2.16-jason.1 set to be updated
--> Processing Dependency: libmysqlclient.so.16(libmysqlclient_16)(64bit) for package: php-mysql
--> Processing Dependency: libmysqlclient.so.16()(64bit) for package: php-mysql
---> Package php-pdo.x86_64 0:5.2.16-jason.1 set to be updated
--> Running transaction check
--> Processing Dependency: libmysqlclient.so.15()(64bit) for package: mysql-connector-odbc
--> Processing Dependency: libmysqlclient.so.15()(64bit) for package: perl-DBD-MySQL
--> Processing Dependency: libmysqlclient.so.15()(64bit) for package: mysql-server
--> Processing Dependency: libmysqlclient.so.15()(64bit) for package: libdbi-dbd-mysql
--> Processing Dependency: libmysqlclient.so.15(libmysqlclient_15)(64bit) for package: mysql-connector-odbc
--> Processing Dependency: libmysqlclient.so.15(libmysqlclient_15)(64bit) for package: perl-DBD-MySQL
--> Processing Dependency: libmysqlclient.so.15(libmysqlclient_15)(64bit) for package: mysql-server
--> Processing Dependency: libmysqlclient.so.15(libmysqlclient_15)(64bit) for package: libdbi-dbd-mysql
--> Processing Dependency: libmysqlclient_r.so.15()(64bit) for package: mysql-connector-odbc
--> Processing Dependency: libmysqlclient_r.so.15()(64bit) for package: mysql-server
--> Processing Dependency: libmysqlclient_r.so.15()(64bit) for package: MySQL-python
--> Processing Dependency: libmysqlclient_r.so.15(libmysqlclient_15)(64bit) for package: mysql-connector-odbc
--> Processing Dependency: libmysqlclient_r.so.15(libmysqlclient_15)(64bit) for package: mysql-server
--> Processing Dependency: libmysqlclient_r.so.15(libmysqlclient_15)(64bit) for package: MySQL-python
---> Package mysql.x86_64 0:5.1.52-jason.1 set to be updated
--> Running transaction check
---> Package mysql-server.x86_64 0:5.1.52-jason.1 set to be updated
---> Package mysqlclient15.x86_64 0:5.0.91-1.jason.1 set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

========================================================================================================================================================================================================
 Package                                          Arch                                      Version                                             Repository                                         Size
========================================================================================================================================================================================================
Updating:
 php                                              x86_64                                    5.2.16-jason.1                                      utterramblings                                    3.8 M
Installing for dependencies:
 mysqlclient15                                    x86_64                                    5.0.91-1.jason.1                                    utterramblings                                    2.0 M
Updating for dependencies:
 mysql                                            x86_64                                    5.1.52-jason.1                                      utterramblings                                    3.5 M
 mysql-server                                     x86_64                                    5.1.52-jason.1                                      utterramblings                                     13 M
 php-cli                                          x86_64                                    5.2.16-jason.1                                      utterramblings                                    2.6 M
 php-common                                       x86_64                                    5.2.16-jason.1                                      utterramblings                                    522 k
 php-devel                                        x86_64                                    5.2.16-jason.1                                      utterramblings                                    557 k
 php-gd                                           x86_64                                    5.2.16-jason.1                                      utterramblings                                    348 k
 php-ldap                                         x86_64                                    5.2.16-jason.1                                      utterramblings                                     63 k
 php-mbstring                                     x86_64                                    5.2.16-jason.1                                      utterramblings                                    1.4 M
 php-mysql                                        x86_64                                    5.2.16-jason.1                                      utterramblings                                    280 k
 php-pdo                                          x86_64                                    5.2.16-jason.1                                      utterramblings                                    169 k

Transaction Summary
========================================================================================================================================================================================================
Install       1 Package(s)
Upgrade      11 Package(s)

Total size: 28 M
Is this ok [y/N]: y
Downloading Packages:
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test


Transaction Check Error:
  file /etc/my.cnf from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/my_print_defaults.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/mysql.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/mysql_config.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/mysql_find_rows.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/mysql_waitpid.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/mysqlaccess.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/mysqladmin.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/mysqldump.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/mysqlshow.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/charsets/Index.xml from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/charsets/cp1250.xml from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/czech/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/danish/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/dutch/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/english/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/estonian/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/french/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/german/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/greek/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/hungarian/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/italian/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/japanese/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/korean/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/norwegian-ny/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/norwegian/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/polish/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/portuguese/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/romanian/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/russian/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/serbian/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/slovak/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/spanish/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/swedish/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/ukrainian/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386

Error Summary
-------------

どうやらこれは、mysql.x86_64とmysql.i386がコンフリクトしているとのことのようです。 mysql.i386を使ってない場合、yum removeしていいとのことでした。

mysqlのどもパッケージは入っているか確認します。

$ yum list installed | grep mysql
libdbi-dbd-mysql.x86_64                   0.8.1a-1.2.2                 installed
mysql.i386                                5.0.77-4.el5_5.4             installed
mysql.x86_64                              5.0.77-4.el5_5.4             installed
mysql-connector-odbc.x86_64               3.51.26r1127-1.el5           installed
mysql-server.x86_64                       5.0.77-4.el5_5.4             installed
php-mysql.x86_64                          5.1.6-27.el5_5.3             installed

.i386なのはmysql.i386だけでした。次に、yum remove(アンインストール)するまえに本当に、使ってないか確認します。

$ mysql --version
mysql  Ver 14.14 Distrib 5.1.52, for redhat-linux-gnu (x86_64) using readline 5.1

i386は使われていなく、x86_64が使われていることが分かりましたので、yum removeします。

$ sudo yum remove mysql.i386
Loaded plugins: fastestmirror
Setting up Remove Process
Resolving Dependencies
--> Running transaction check
---> Package mysql.i386 0:5.0.77-4.el5_5.4 set to be erased
--> Finished Dependency Resolution

Dependencies Resolved

========================================================================================================================================================================================================
 Package                                     Arch                                       Version                                                   Repository                                       Size
========================================================================================================================================================================================================
Removing:
 mysql                                       i386                                       5.0.77-4.el5_5.4                                          installed                                       7.9 M

Transaction Summary
========================================================================================================================================================================================================
Remove        1 Package(s)
Reinstall     0 Package(s)
Downgrade     0 Package(s)

Is this ok [y/N]: y
Downloading Packages:
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
  Erasing        : mysql                                                                                                                                                                            1/1 

Removed:
  mysql.i386 0:5.0.77-4.el5_5.4    

アンインストールされたようです。

一応、yum list installedでremoveされたか確認します。

$ yum list installed | grep mysql
libdbi-dbd-mysql.x86_64                   0.8.1a-1.2.2                 installed
mysql.i386                                5.0.77-4.el5_5.4             installed
mysql.x86_64                              5.0.77-4.el5_5.4             installed
mysql-connector-odbc.x86_64               3.51.26r1127-1.el5           installed
mysql-server.x86_64                       5.0.77-4.el5_5.4             installed
php-mysql.x86_64                          5.1.6-27.el5_5.3             installed

この後、再度 yum update phpをしたらうまくPHPがアップデートされました。

トラブル解決2件:SSHにログインできない& svn upできない

suin : 技術全般 2010/12/1 13:09

Blogger's Avatar

SSHにログインしようとするとToo many authentication failuresと言われる

MacのターミナルでSSHにログインしようとすると次のようなメッセージが出てログインできません。

Received disconnect from XXX.XXX.XXX.XXX: 2: Too many authentication failures for *username*

このように解決しました

Macのターミナルを起動

$ ssh-add -D
$ open ~/.ssh/config
# お使いのエディタがあればそれでひらいてください。
# configファイルが無ければ作ってください。テキストでいいです。

configファイルの最初に以下の行を追加

IdentitiesOnly yes

svn upするとsvn: access to '*url*' forbiddenと言われる

svn upしようとすると、svn: access to '*url*' forbiddenと言われて、アップデートが失敗しました。 他のマシンで同じようにsvn upしたらできたので、問題が起きたPCの問題だと分かりました。

このように解決しました

前回、svn upしたユーザが違っていたのが問題だったようです。 前回ユーザ suin で sudo svn up していたのに、今回は root で svn up しようとしました。 そこで、suinユーザで sudo svn up したら、問題なくアップデートできました。

mainfile.phpをサイトごとに切り替える開発テクニック

suin : XOOPS » TIPS小ネタ 2010/11/1 17:40

Blogger's Avatar

mainfile.phpはXOOPSの設定ファイルで、XOOPSのパスやデータベースのアカウント情報などが書かれています。これらの設定情報は、当然 環境に依存しています。

開発フローを、開発→ステージング→プロダクションという流れでやる場合、同じサイトが少なくとも3つ以上できてしまいます。そうすると、mainfile.phpも複数できあがるわけです。ところが、XOOPS Cube Legacyはサイトプロフィールという概念がないため、mainfile.phpの取り扱いは悩ましいものがあります。(他のCMS、Drupalなどではあると聞いています。)

複数のmainfile.php問題を解決する方法はいくつか考えられます。

1. どの環境もそっくりの環境にする

XOOPS_ROOT_PATHなどはdirname(__FILE__)で解決し、データベースのアカウント情報はどのサーバでも共通のものにするという手法です。 ただ、この方法だとチームで開発に取り組む場合、あまりうまくいきません。SVNで管理しているサイトだと、お互いのmainfile.phpを上書きしあう心配があります。

2. mainfile.phpはSVNで管理しない

mainfile.phpは環境依存が強いため、SVNでは管理しないようにしておく方法があります。こうしておくと、チームでお互いのmainfile.phpを上書きする心配もありません。ところが、この方法では、リポジトリにmainfile.phpがないのが欠点になります。mainfile.phpが無いので、チェックアウトしてきても直ぐに動かせません。また、そのサイト全体で使われている定数をmainfile.phpに書いておくことがありますが、定数をいちいち手動で追加しなければなりません。(本来、環境依存ではない定数は、/settings/definition.phpに書くべきですが。)

そこで、今回紹介するのは、mainfile.phpをサイトごとに切り替える方法です。

まず、サイトごとのmainfile.phpを適当に名前を変更して、settingsの下に置きます。 例えば、今ローカル環境にあるmainfile.phpは開発環境なので、名前をmainfile.dev.phpに変えて、settingsに移動します。

.
├── mainfile.php
├── settings
│   ├── mainfile.dev.php
│   ├── mainfile.stag.php
│   └── mainfile.prod.php
(略)

次に、XOOPS_ROOT_PATHに空のmainfile.phpを作り、そこに下のコードをコピペします。

<?php

require XoopsProfiler::getProfile();

class XoopsProfiler
{
	// ホスト名 => ファイル名
	protected static $map = array(
		'suinasia.local' => 'mainfile.dev.php', // 開発
		'stag.suin.asia' => 'mainfile.stag.php', // ステージング
		'suin.asia'      => 'mainfile.prod.php', // プロダクション
	);

	public static function getProfile()
	{
		$xoopsRootPath = dirname(__FILE__);
		$serverName = $_SERVER['SERVER_NAME'];
		$ds = DIRECTORY_SEPARATOR;

		if ( !isset(self::$map[$serverName]) )
		{
			trigger_error("Profile not found.");
			die;
		}

		$mainfile = self::$map[$serverName];
		$path = $xoopsRootPath.$ds.'settings'.$ds.$mainfile;

		return $path;
	}

}

あとは、$map配列のところを適宜書き換えるだけです。 配列のキーはホスト名で、値はそのホストで使うmainfile.phpになります。

上のコードを少し書き換えれば、開発環境でも複数のデータベースを簡単に切り替えたり、いろいろ応用できると思います。

MySQL5.1で遅いクエリーのログを取る

suin : 技術全般 2010/10/21 13:12

Blogger's Avatar

MySQLには遅いクエリーを改善するために、指定した秒数以上かかったクエリーをログに取っておいてくれる機能があります。それをスロークエリーログといいます。この記事では、スロークエリーログを有効にして、実際に作られたログを確認するところまで順を追って説明します。

ひとまずrootになる。

sudo su - root
# とか
su - root

MySQLの設定ファイルを編集します。

vim /etc/my.cnf
# vim: command not foundな人は vi /etc/my.cnf

iとタイプして編集モードへ。

slow_query_log=1 # スロークエリーログを有効にします。ONとかOnと書いても有効にならないので注意。
slow_query_log_file=mysql-slow.log # フルパスじゃないとたぶん、datadirにできます。
long_query_time=1 # 秒数で指定。この例では1秒以上かかるクエリはログに残る

escキーを押して、:wqとタイプ後Enterで上書き保存

MySQLの再起動を忘れずに。

/etc/rc.d/init.d/mysqld restart

MySQLにログインしてみよう。

mysql -u root
# とか
mysql -u root -p

2秒かかるクエリーを実行してみる。

mysql> SELECT SLEEP(2);
+----------+
| SLEEP(2) |
+----------+
|        0 |
+----------+
1 row in set (2.00 sec)

MySQLから抜けます。

mysql> exit

slow_query_log_fileがあるディレクトリに移動。

cd /var/lib/mysql/

中身を見てみよう。

cat mysql-slow.log

# Time: 101021 13:04:49
# User@Host: root[root] @ localhost []
# Query_time: 2.002632  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 0
SET timestamp=1287633889;
SELECT SLEEP(2);

ちゃんとログが取れてるのが確認できました。

SELECTなのにテーブルにロックが掛かる!〜InnoDBトランザクションにおけるINSERT INTO SELECT FROMの罠〜

suin : 技術全般 2010/10/14 19:37

Blogger's Avatar

MySQLのInnoDBはトランザクションが使えたり、行ロックが使えたりして、データの整合性の点でMyISAMに比べて優れています。 業務系アプリになると、データの整合性が重視されることも多く、トランザクションを使うことも増えます。

今回、そのトランザクションを使っていて、思いもよらないクエリがきっかけで、テーブルにロックが掛かってハマりました。

テーブル構造はこのような感じ...。

CREATE TABLE `working` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `col` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `col` (`col`)
) ENGINE=InnoDB;

もう一個まったく同じテーブルを作ります。

CREATE TABLE `backup` LIKE `working`;

workingにデータを入れます。

INSERT INTO `working` (`col`) VALUES ('1'), ('2'), ('3');

SELECT * FROM `working`;

+----+-----+
| id | col |
+----+-----+
|  1 |   1 |
|  2 |   2 |
|  3 |   3 |
+----+-----+

ちなみに、分離レベルを見ておきます。

SELECT @@tx_isolation;

+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+

さて、もう察しが付いているかもしれませんが、これからworkingからbackupにデータを移すクエリを実行したいと思います。

クライアント1

クライアント1は、BEGINしてトランザクションを開始し、INSERT INTO t SELECT ... FROM s WHERE...を使って、データコピーのクエリを実行します。

mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO `backup` (`col`) SELECT `col` FROM `working` WHERE `col` = 3;
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

この処理は一瞬で終わりますが、COMMITやROLLBACKせず、トランザクションはそのままにしておきます。

クライアント2

クライアント2では、普通にworkingにINSERTします。

mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM `backup`;
Empty set (0.00 sec)

mysql> INSERT INTO `working` (`col`) VALUES ('4');

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

まず、backupテーブルはまだ空です。これはクライアント1がコミットせずトランザクションを維持しているからです。しかし、ここでworkへのINSERTが長く待たされます。挙句に、「Lock wait timeout exceeded」というエラーが出て、クライアント2のトランザクションが終了してしまいます。

一見すると、とても奇妙な挙動です。クライアント1は、サブクエリーでworkingテーブルにSELECTしているだけです。UPDATESELECT ... FOR UPDATEをかけているわけではないからです。

ところが、良く調べてみると、INSERT INTO SELECT FROMの形でSELECTされたテーブルにロックが掛かることがあるとマニュアルに書いてありました。

INSERT INTO T SELECT ... FROM S WHERE ... は T に挿入された各行に、ギャップロックなしの排他インデックスレコードロックを設定します。innodb_locks_unsafe_for_binlog が有効であるかトランザクション遮断レベルが READ COMMITTED である場合には、InnoDB は S での検索を一貫性読み取り (ロックなし) として行います。それ以外の場合、InnoDB は S から取得した行に共有ネクストキーロックを設定します。InnoDB は後者の場合にロックを設定する必要があります。バックアップからの前進復旧では、すべての SQL ステートメントはそれが元々行われたのとまったく同じ方法で実行されなければいけません。

これを読む限りでは、workingテーブルにネクストキーロックがかかってしまったようです。注目して欲しいのは、クライアント1のクエリの`col` = 3と、クライアント2の(`col`) VALUES ('4')です。ネクストキーロックの範囲や発動条件はよく調べていないのでなんとも言えませんが、colの数字が3と4で隣り合っています。これによってロックが発動したようです。

ためしに、下のように隣接していない場合はロックが掛かりません。

# クライアント1
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO `backup` (`col`) SELECT `col` FROM `working` WHERE `col` = 1;
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

# クライアント2
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO `working` (`col`) VALUES ('4');
Query OK, 1 row affected (0.00 sec)

また比較として、単なるSELECTINSERTでは、ロックはかかりません。

# クライアント1
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO `working` (`col`) VALUES ('3');
Query OK, 1 row affected (0.00 sec)

# クライアント2
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO `working` (`col`) VALUES ('4');
Query OK, 1 row affected (0.00 sec)

もし、以下の条件に当てはまる処理は、INSERT INTO SELECT FROMのサブクエリを独立させてPHPで結果をINSERTに渡すような実装にしたほうが良いかもしれません。

  • workingは頻繁にINSERTされる。(そして待たされたり、タイムアウトしては困る。)
  • INSERT INTO SELECT FROMのあるトランザクションが非常に長い。
  • クライアント2のINSERTはクライアント1のトランザクションに全く関係ないデータである。
余談

今回はトランザクションにはまりましたが、ROLLBACKは便利そうです。大量のテストデータとテストパターンがあって、毎回DBをリストアしてテストしなおすような計画では、テストが完了するごとにROLLBACKすると良さそうです。一瞬でDBがもとに戻ります。

CentOSにSSH2を入れてみた

suin : PHP 2010/10/4 17:22

Blogger's Avatar

PHPにはSSH2の関数が用意されています。ここでは、CentOSにSSH2を入れる手順を書いておきます。試行錯誤込みで書いてますので、手っ取り早くうまく言ったコマンドだけ知りたい人はこのセクションの最後に飛んでください。

SSH2はPECLの拡張モジュールなので、下記のコマンドを実行すればいいとのこと。

pecl install ssh2-beta

実行してみた。

bash: pecl: command not found

...(-_-;;;

PECLが入ってなかったとは。PECLを入れるために下記のコマンドを実行しました。

yum -y install php-pear

すると、こんどは、Missing Dependencyのエラーが。なんという失敗続き;;

php-devel-5.1.6-27.el5.x86_64 from base has depsolving problems
  --> Missing Dependency: php = 5.1.6-27.el5 is needed by package php-devel-5.1.6-27.el5.x86_64 (base)
Error: Missing Dependency: php = 5.1.6-27.el5 is needed by package php-devel-5.1.6-27.el5.x86_64 (base)
 You could try using --skip-broken to work around the problem
 You could try running: package-cleanup --problems
                        package-cleanup --dupes
                        rpm -Va --nofiles --nodigest
The program package-cleanup is found in the yum-utils package.

稼働中のPHPのバージョンが5.2.14だったので、そのPHPをとってきたリポジトリからyumしました。

yum install --enablerepo=utterramblings php-pear

which peclとコマンドをたたいて、peclが入っているのを確認。

libssh2が必要らしいので、こちらもyumで取ってきます。

yum -y install libssh2
yum -y install libssh2-devel

peclからssh2を入れます。コマンドは、pecl install ssh2を実行。すぐに怒られました。

Failed to download pecl/ssh2 within preferred state "stable", latest release is version 0.11.0, stability "beta", use "channel://pecl.php.net/ssh2-0.11.0" to install
install failed

仕方がないので、下記のコマンドを実行。

 pecl install channel://pecl.php.net/ssh2-0.11.0

ssh2のインストール中にlibssh2の場所を聞かれます。私の場合、/usrではなかったのでパスを指定しました。

libssh2 prefix? [/usr] : /usr/lib64

しかし、これではうまくいかずエラーが出てしまいました。今日は怒られてばかりです(笑)

ERROR: `/tmp/pear/download/ssh2-0.11.0/configure --with-ssh2=/usr/lib' failed

ググったらlibssh2-develも入れないといけないとわかったので、以下のコマンドを実行します。

 yum install libssh2-devel

その後、再度peclコマンドでssh2をインストールします。今度こそうまくいったようなので、php.iniを編集します。

cd /etc/php.d/
 # php.iniを設定しますが、私の環境では.iniを分割していたので、適当にzip.iniをコピーして編集しました。
cp zip.ini ssh2.ini
vim ssh2.in

extension=ssh2.soに書き換えて保存します。あとは、Apacheを再起動して終わりです。

/etc/init.d/httpd restart

結局うまくいったコマンド

# yum install --enablerepo=utterramblings php-pear
 
# yum -y install libssh2
# yum install libssh2-devel
 
# pecl install channel://pecl.php.net/ssh2-0.11.0
 
# cd /etc/php.d/
 ## php.iniを設定しますが、私の環境では.iniを分割していたので、適当にzip.iniをコピーして編集しました。
# cp zip.ini ssh2.ini
# vim ssh2.ini

 	extension=ssh2.soと書き込み

# /etc/init.d/httpd restart

[PHPでサマータイム第2弾] タイムゾーンの識別子を取得してきてセレクトを作ろう

suin : PHP 2010/9/30 22:56

Blogger's Avatar

ユーザがサマータイムかどうか、そしてサマータイムのオフセットをいくつか、といったデータはユーザがどこに住んでいるか分かっている必要があります。PHP5.2では、タイムゾーンとサマータイムを考慮した、タイムゾーン識別子をいくつも用意してくれています。識別子一覧の取得方法は前回のブログで書きました。識別子の大部分は、地域/都市名という書式になっています。

サマータイムを反映するには、内部的にユーザデータとタイムゾーン識別子を紐付けておく必要があるでしょう。そのため、こうしたシステムでユーザに識別子を選んでもらうインターフェイスが必要になります。今回は、タイムゾーン識別子一覧からセレクトボックスを作る方法を説明しようと思います。

前回の記事に引き続き、PHPのDateTimeZoneクラスを継承したRyus_DateTimeZoneクラスを使って、実装してみようと思います。今回、新しく、Ryus_DateTimeZoneに以下のメソッドを追加しました。識別子は、地域・国都市の順にスラッシュで区切られています。このメソッドは、地域と国都市に分解して、多次元配列にして返すものです。PHP5で非推奨になった修飾子とUTCは除外されます。

	public static function getIdentifiersAsArray()
	{
		$identifiers = self::listIdentifiers();

		$result = array();

		foreach ( $identifiers as $identifier )
		{
			if ( $identifier === 'UTC' )
			{
				continue;
			}

			$parts = explode('/', $identifier);
			$area = $parts[0];
			$city1 = $parts[1];

			if ( isset($parts[2]) )
			{
				$city2 = $parts[2];
				$result[$area][$city1.' > '.$city2] = $identifier;
			}
			else
			{
				$result[$area][$city1] = $identifier;
			}
		}

		return $result;
	}

そして、下が上のメソッドを使ったセレクトボックスの生成方法です。地域ごとにoptgroupタグでくくったものが生成されます。

<?php 
require 'Ryus_DateTimeZone.php';
$ret = Ryus_DateTimeZone::getIdentifiersAsArray();
?>
<select name="timezone">
<option value="">--------</option>
<? foreach ( $ret as $area => $cities ) :?>
<optgroup label="<? echo $area ?>">
	<? foreach ( $cities as $city => $identifier ) : ?>
	<option value="<? echo $identifier ?>"><? echo $city ?></option>
	<? endforeach ?>
</optgroup>
<? endforeach ?>
</select>

このリストを生成してみるとわかりますが、optgroupで地域別にくくったと言っても選択肢が多すぎて、決してユーザフレンドリーなインターフェイスとは言えないものになります。どのようにしたら、もうすこし使いやすいセレクトになるか考える必要がありそうです。次回につづく...

今回作成したサンプルのダウンロード:

sample02.zip

XOOPSの設定画面をちょこっと使い易くする?

hamaco : XOOPS » TIPS小ネタ 2010/9/30 18:55

Blogger's Avatar

こんにちは hamacoです。

今回JavaScriptネタが思い浮かばなかったので普通のPHPネタです。
個人的にXOOPS管理画面の一般設定で設定完了後に良く分からないページに飛ばされるのがムカついたので、ちょっと弄って元のページにリダイレクトするようにしてみました。

なんか前にもやったような気がするけど気にしない

{XOOPS_ROOT_PATH}/modules/legacy/admin/actions/PreferencesEdit.class.php を開いて以下の様に置き換えます。

line 304
$controller->executeForward("./index.php?action=PreferenceList");

include_once XOOPS_ROOT_PATH . "/include/cp_functions.php";
$controller->executeRedirect("./index.php?action=PreferenceEdit&confcat_id=" .xoops_getrequest('confcat_id'), 2, '設定を完了しました');
に。

line 352
$controller->executeForward(XOOPS_MODULE_URL . '/' . $this->_mMaster->mModule->get('dirname') . '/admin/');

include_once XOOPS_ROOT_PATH . "/include/cp_functions.php";
$controller->executeRedirect("./index.php?action=PreferenceEdit&confmod_id=" .xoops_getrequest('confmod_id'), 2, '設定を完了しました');
に変えると、全般設定やモジュールの一般設定の変更をした時に設定完了メッセージを表示し、設定画面に戻るようになります。

好みによりますが、これで多少快適にXOOPS使えるようになるんじゃないかなー。

スタッフブログ最新
カテゴリ一覧

〒104-0061 東京都中央区銀座1丁目3番3号 G1ビル7階
お問い合わせ TEL 03-3524-8860

Copyright(c) 2012 RYUS.All Rights Reserved.