‘mysql’ タグのついている投稿

他のパッケージのaptitude install後にMySQLが起動しない問題

他の環境では多分あまり発生しないかと思いますが、自分の環境では毎回のように発生する上、対処方法をいつも忘れるのでメモ。

環境はdebian squeeze。

# /etc/init.d/mysql start
[FAIL] Starting MySQL database server: mysqld . . . . . . . . . . . . . . failed!

ログも一切出ないので困っていましたが、ファイルのパーミッションの問題でした。

# cd /var/lib/mysql/
(省略)
-rw-rw---- 1 mysql mysql      126 2014-02-27 07:45 mysql-bin.000022
-rw-rw---- 1 mysql root     26620 2014-02-27 07:45 mysql-bin.000023
-rw-rw---- 1 mysql root   1061358 2014-02-27 07:45 mysql-bin.000024
-rw-rw---- 1 root  root     26620 2014-02-27 07:45 mysql-bin.000025
-rw-rw---- 1 root  root   1061358 2014-02-27 07:45 mysql-bin.000026
-rw-rw---- 1 mysql mysql      494 2014-02-27 07:45 mysql-bin.index

mysql-binファイルがroot権限で作られていました。

片っ端からchownして解決です。

# chown mysql:mysql mysql-bin.000023
# chown mysql:mysql mysql-bin.000024
# chown mysql:mysql mysql-bin.000025
# chown mysql:mysql mysql-bin.000026
# /etc/init.d/mysql start
[ ok ] Starting MySQL database server: mysqld ..

根本的な原因は何なんだろうなぁ。


Symfony2のdoctrine2をenumに対応させる

doctrine2がenumに対応していないので、既存のデータベースからEntityを作ろうとした時にエラーが出ることがあります。

$ php app/console doctrine:mapping:convert yml ./src/Test/HogeBundle/Resources/config/doctrine/metadata/orm --from-database --force

  [Doctrine\DBAL\DBALException]
  Unknown database type enum requested, Doctrine\DBAL\Platforms\MySqlPlatform may not support it.

その場合は、doctrine2のドキュメントによると、enumをstringに関連づければ良いようです。

Mysql Enums — Doctrine 2 ORM 2.1 documentation

BundleのbootでEntityManagerを取得して、マッピングを行います。

<?php

namespace Test\HogeBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class TestHogeBundle extends Bundle
{
    public function boot() {
        $em = $this->container->get('doctrine.orm.default_entity_manager');
        $conn = $em->getConnection();
        $conn->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
    }
}

他の方法として、Enumタイプを作成して関連付けることもできるようです。

※追記

app/config/config.phpに書く方法が紹介されていました。

Doctrine の DBAL レイヤーの使用方法 | Symfony2日本語ドキュメント

$container->loadFromExtension('doctrine', array(
    'dbal' => array(
        'connections' => array(
            'default' => array(
                'mapping_types' => array(
                    'enum'  => 'string',
                ),
            ),
        ),
    ),
));

試していませんが、これでもいいらしいです。


Windows版MySQLの配布形態ごとの違い

Windows版のMySQL Server 5.5には、3種類の配布形態があります。

MySQL Installer

http://www-jp.mysql.com/downloads/installer/
msi形式のファイルです。
mysql-installer-5.5.21.0.msiのようなファイル名になっています。

サーバーに加えて、サンプルとドキュメント、Connectors、Workbenchなどのツールが含まれます。一番多くの人におすすめできるパッケージとの事。

The Complete Package

http://www-jp.mysql.com/downloads/mysql/
WS000006

上2つがComplete Packageです。mysql-5.5.21-win32.msiのようなファイル名になっています。組み込みサーバやベンチマークスイートなどが含まれます。

The Noinstall Archive

Complete Packageと同じURLで配布されています。上の画像では、Zip Archiveと書かれているもののうち、上2つです。mysql-5.5.21-win32.zipのようなファイル名になっています。

ファイルサイズが大きいのは、テストやベンチマークなどに加えて、デバッグ情報(pdb:プログラムデバッグデータベースファイル)が付属しているためです。

ただし、このzipファイルにはMySQLInstanceConfig.exeは含まれていません。my.iniファイルの作成とサービス登録は自力で行う必要があります。

ちなみに最後のひとつはソースコードです。バイナリは含まれていません。

それぞれのパッケージのインストール方法と、インストーラーの挙動はpdfで公開されています。
http://downloads.mysql.com/docs/mysql-windows-excerpt-5.5-en.pdf

表です。5.1のEssentialsを参考にしているので間違っているかもしれません。
出典:http://downloads.mysql.com/docs/mysql-windows-excerpt-5.1-en.pdf

 

Installer

Complete

No-install

Installer

あり

あり

なし

MySQL Server Instance Config Wizard

あり

あり

なし

Test Suite

なし

あり

なし

MySQL Server

あり

あり

あり

MySQL Client Programs

あり

あり

あり

C Headers/Libraries

あり

あり

あり

Embedded Server

なし

オプション

あり

Scripts and Examples

なし

オプション

あり

5.1まであった、Essentialsはなくなったようです。

MySQLのmsi形式のインストーラーは、別のMySQLInstaller.exeを展開して使うためにあるようなものなので、インストール先ディレクトリをmsiexecを使ったコマンドラインで指定したりできません。

NSISなどに組み込んで、インストール先を指定したい場合はzipで配布されているNo-install版を使うのが正しいようです。


MySQL Workbenchからschema.ymlを生成する

MySQL Workbenchからsymfony+Doctrine用のschema.ymlを書き出せないかなぁとつぶやいたら@hidenorigotoさんに教えていただいたので試してみました。
http://twitter.com/#!/hidenorigoto/status/38153994970988544

MySQL Workbench schema exporter

MySQL Workbench schema exporterは、MySQL WorkbenchプラグインのMySQL Workbench Doctrine Pluginにインスパイアを受けて開発されたようです。
が、こちらのプラグインはすでにメンテされていないようです。

開発終了した理由がぞろぞろ書いてありますが、要約すると「LUAが…」ってことみたいです。

MySQL Workbench schema exporterはPHPで書かれています。MySQL Workbenchのmwbファイルを読み込んでパース、フォーマッタを指定してそれぞれの形式を書き出すようです。
ちなみにmwbファイルはZIP圧縮されたXMLです。あと、SQLite3のデータが入ってました。

注意点としてPHP 5.3以降でないと実行できません…
いつものdebian環境では5.2を使ってるので、Windows版の5.3をダウンロードしてインストールしました。

まずはexampleディレクトリに移動します。

C:\Users\test\Downloads\johmue-mysql-workbench-schema-exporter-7d08e29\example>php -v 
PHP 5.3.5 (cli) (built: Jan  5 2011 20:36:18) 
Copyright (c) 1997-2010 The PHP Group 
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies

example/data/にtest.mwbがあり、サンプルではこのファイルを使います。

ちなみにサンプルのEER(Enhanced Entity-Relationship) diagramはこんな感じです。

test.mwb

C:\Users\test\Downloads\johmue-mysql-workbench-schema-exporter-7d08e29\example>php .\doctrine1.yaml.php 
<textarea cols="100" rows="50">Bureau: 
  tableName: mydb.bureaus 
  columns: 
    id: 
      type: integer(4) 
      primary: true 
      notnull: true 
      autoincrement: true 
    room: 
      type: string(45) 
  indexes: 
    testIndex: 
      fields: [room] 
      type: unique 
  options: 
    charset: utf8 
    type: InnoDB

Email: 
  actAs: 
    timestampable: 
  tableName: mydb.emails 
  columns: 
    id: 
      type: integer(4) 
      primary: true 
      notnull: true 
      autoincrement: true 
    email: 
      type: string(255) 
    users_id: 
      type: integer(4) 
      primary: true 
      notnull: true 
  relations: 
    User: 
      class: User 
      local: users_id 
      foreign: id 
      foreignAlias: Emails 
      onDelete: no action 
      onUpdate: no action 
  indexes: 
    fk_Emails_Users: 
      fields: [users_id] 
  options: 
    charset: utf8 
    type: InnoDB

User: 
  actAs: 
    timestampable: 
  tableName: mydb.users 
  columns: 
    id: 
      type: integer(4) 
      primary: true 
      notnull: true 
      autoincrement: true 
    name: 
      type: string(255) 
  options: 
    charset: utf8 
    type: InnoDB

UsersBureaus: 
  tableName: mydb.users_bureaus 
  columns: 
    users_id: 
      type: integer(4) 
      primary: true 
      notnull: true 
    bureaus_id: 
      type: integer(4) 
      primary: true 
      notnull: true 
  relations: 
    User: 
      class: User 
      local: users_id 
      foreign: id 
      foreignAlias: UsersBureauss 
      onDelete: no action 
      onUpdate: no action 
    Bureau: 
      class: Bureau 
      local: bureaus_id 
      foreign: id 
      foreignAlias: UsersBureauss 
      onDelete: no action 
      onUpdate: no action 
  indexes: 
    fk_users_bureaus_bureaus1: 
      fields: [bureaus_id] 
  options: 
    charset: utf8 
    type: InnoDB

Testtable: 
  tableName: mydb2.testtable 
  columns: 
    id: 
      type: integer(4) 
      primary: true 
      notnull: true 
  options: 
    charset: utf8 
    type: InnoDB 
</textarea><br><br>1 MB used<br>0.055 sec needed

というわけで、リレーションやインデックスなども書きだされるようです。

HTMLのタグはdoctrine1.yaml.phpの中に書いてあるので、CLIから使うときは適当に外してください。

timestampableなどのビヘイビアに関しては、コメント欄に書くことで出力できるようです。

{d:actAs} 
  actAs: 
    timestampable: 
{/d:actAs}

この仕様はちょっと微妙な気が…

created_atとupdated_atがあったらtimestampable付けるとかの方が楽だなぁ、と。

作っちゃった後の全テーブルにコメント指定して回るのはちょっと辛いので。

サーバにPHP 5.3が入っているなら、symfony taskでmwbからschema.ymlの生成と、ActAsの追加をやってしまうのがいいかな、と思いました。

うーん、個人的にはMySQL Workbench上で完結したいから、プラグインの方が便利な気はするんですけどねぇ。LUAとは言わなくてもPythonスクリプティング対応しているようなので、Pythonに書き直すとか…

この後、60テーブルほどのファイルを変換してみましたが、問題なく実行できました。

追記(2011/02/19)

注意点がいくつかあります。

というか、致命的かも。

1.NOT NULLのchar型にDEFAULT値”を入れるとNULLに変換される

これはDoctrineのbuild –sqlがおかしいかな…

column_name:

  type: char(3)

  notnull: true

  default: ”

column_name char(3) DEFAULT NULL NOT NULLとかいう矛盾を持ったクエリが生成されます。

ちなみにvarcharは大丈夫です。

default: ”の行は削除しましょう。

2.DECIMALやFLOATの最大桁数と少数点の値が逆になる

ひどい。

例えばMySQL WorkbenchでDECIMAL(15,4)と指定したカラムがDECIMAL(4,15)と書き出されます。

column_name:

  type: decimal(4,15)

  notnull: true

  default: ‘0.0000’

もちろん、ちゃんとMySQL Workbenchからクエリのエクスポートをしたときは15,4になります。

置換で何とか…

うーん、やっぱりMySQL WorkbenchでDBをあらかじめ作成しておいてから→doctrine:build-schema→schema.yml修正が妥当かなぁ。


PHPのDateTimeの結果が-0001-11-30 00:00:00になる現象について

mySQLなどで、日時を0000-00-00 00:00:00としてデータベースに格納しておくことがありますが、これを読み込んでそのままPHPのDateTimeオブジェクトに渡すと、出力が-0001-11-30 00:00:00になってしまいます。

$a = new DateTime('0000-00-00 00:00:00');
echo $a->format('Y-m-d H:i:s');
// Output: -0001-11-30 00:00:00

PHP :: Bug #42971 :: DataTime::format(): not well formated data ‘0000-00-00 00:00:00’

で、これはバグではないと言われているので、どういうことかと考えてみると、0000-00-00は存在しない0月0日を指定しているので、0月は繰り下がって-1年12月0日、さらに0日も繰り下がって-1年11月30日、となるわけですね。

データベースとPHPの文化の違い、というところでしょうか。

ちなみにDateTime型、コンストラクタにNULLを渡すと現在時刻のインスタンスが生成されるので、データベースの値をNULLにしておくと、現在時刻になってしまいます。うーん…symfonyのDoctrineでNULL判定したい場合はどうすればいいんだ…

$row->getDateTimeObject('deleted_at')

みたいなことがやりたいのですが。

sfDoctrineRecordも

    $type = $this->getTable()->getTypeOf($dateFieldName);
    if ($type == 'date' || $type == 'timestamp')
    {
      return new DateTime($this->get($dateFieldName));
    }

こうなってるからオーバーライドするしかないのかな。