Symfoware

Symfowareについての考察blog

H2SQLのバックアップとリストア

H2SQL、バックアップとリストア用のスクリプトが用意されているとのこと。
Upgrade, Backup, and Restore

こちらで作成した環境で試してみます。
FreeBSD 10.1でH2 Database Engineを起動する


H2SQLの起動



webコンソールを使用したかったので、tcpAllowOthersオプションを指定し
起動しておきました。


# cd /usr/local/opt/h2/bin
# ./h2.sh -webAllowOthers -tcpAllowOthers -baseDir /usr/local/opt/h2/data







バックアップとリストア



バックアップの方法は2種類あるようです。

まず、スクリプトを使用するパターン。


# cd /usr/local/opt/h2/bin
# java -cp h2*.jar org.h2.tools.Script -url jdbc:h2:tcp://192.168.1.103/sample -script sample.zip -options compression zip



sample.zipが出力されました。


以下のコマンドでリストアできます。


# cd /usr/local/opt/h2/bin/
# java -cp h2*.jar org.h2.tools.RunScript -url jdbc:h2:tcp://192.168.1.103/sample -script sample.zip -options compression zip



この方法でバックアップを行った場合、
sqlスクリプトが生成されます。




続いて、SQLで指定する方法。
webコンソールを使用して、


BACKUP TO '/usr/local/opt/h2/backup.zip'



というコマンドを実行します。

621_01.png

621_02.png


この方法のバックアップは、データベースファイル自体がzip圧縮されます。
リストアする場合は、zipファイルを解凍して、
データベースファイルを任意の位置に復元します。

テーマ:サーバ - ジャンル:コンピュータ

  1. 2015/07/05(日) 17:03:57|
  2. H2 Database Engine
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

FreeBSD 10.1でH2 Database Engineを起動する

ずいぶん前にDebianでH2 Database Engineを動かしてみました。
DebianでH2 Database Engineを起動し、別端末からJavaで接続する

FreeBSD 10.1で同じことをやってみます。

OpenJDKのインストール



jvmはOpenJDKを使用することにしました。
こちらの手順でインストールしています。
FreeBSD 10.1にOpenJDK 8をインストールする



H2 Databaseの起動



使用するバージョンは現時点(2015/7/5)で最新の1.4.187です。
こちらの、All Platformsのリンクからダウンロード、展開します。
http://www.h2database.com/html/main.html

/usr/local/opt/h2に配置しました。
以前の記事を参考に、

・-tcpAllowOthersで、外部接続許可
・-baseDir /usr/local/opt/h2/dataで、データの保存先を指定

というオプションを指定し、起動します。


# cd /usr/local/opt/h2/bin
# chmod +x h2.sh
# ./h2.sh -tcpAllowOthers -baseDir /usr/local/opt/h2/data
Web Console server running at http://192.168.1.103:8082 (only local connections)
Failed to start a browser to open the URL http://192.168.1.103:8082: Browser detection failed and system property h2.browser not set
TCP server running at tcp://192.168.1.103:9092 (others can connect)
PG server running at pg://192.168.1.103:5435 (only local connections)








外部からの接続



Javaでサンプルを書いてみます。
h2-1.4.187.jarをビルドパスに含めておきます。


  1. package sample;
  2. import java.sql.Connection;
  3. import java.sql.DriverManager;
  4. import java.sql.ResultSet;
  5. import java.sql.Statement;
  6. public class MainProcess {
  7.     
  8.     public static void main(String[] args) throws Exception {
  9.         
  10.         //接続
  11.         String url = "jdbc:h2:tcp://192.168.1.103/sample";
  12.         Connection con = DriverManager.getConnection(url);
  13.         
  14.         Statement stmt = con.createStatement();
  15.         // テーブル作成
  16.         stmt.execute("CREATE TABLE IF NOT EXISTS test (id int, name varchar(10))");
  17.         stmt.execute("INSERT INTO test (id, name) values (1, '日本語テスト')");
  18.         
  19.         ResultSet rs = stmt.executeQuery("SELECT * FROM test");
  20.         
  21.         while(rs.next()) {
  22.             System.out.println(rs.getString("name"));
  23.         }
  24.         rs.close();
  25.         
  26.         stmt.close();
  27.         con.commit();
  28.         con.close();
  29.     }
  30.     
  31. }




実行結果はこちら。


日本語テスト




狙い通り、「/usr/local/opt/h2/data」に「sample.mv.db」という
ファイルが作成されました。

テーマ:サーバ - ジャンル:コンピュータ

  1. 2015/07/05(日) 16:31:49|
  2. H2 Database Engine
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

H2 Database EngineにMySQLとのLINKED TABLEを作成する

H2 Database Engineのリファレンスを見ていると、LINKED TABLEという
機能についての解説がありました。

Linked Tables

どうやら、別のデータベースのテーブルを仮想的にH2にあるテーブルのように見せる機能みたいです。
これはおもしろいかも。

MySQLとのLINKED TABLEを作って見ました。






MySQLにデータベースとテーブルの作成



H2からリンクするデータベースとテーブルをMySQLに作成します。

データベースとテーブル、テストデータの投入に使用したクエリは以下のとおり。


CREATE DATABASE linkedtest CHARACTER SET utf8 COLLATE utf8_general_ci;
use linkedtest;
CREATE TABLE T_MYSQL (id integer, val varchar(20));

INSERT INTO T_MYSQL(id, val) value (1, 'mysqlval_1');
INSERT INTO T_MYSQL(id, val) value (2, 'mysqlval_2');
INSERT INTO T_MYSQL(id, val) value (3, 'mysqlval_3');
INSERT INTO T_MYSQL(id, val) value (4, 'mysqlval_4');
INSERT INTO T_MYSQL(id, val) value (5, 'mysqlval_5');
INSERT INTO T_MYSQL(id, val) value (6, 'mysqlval_6');
INSERT INTO T_MYSQL(id, val) value (7, 'mysqlval_7');
INSERT INTO T_MYSQL(id, val) value (8, 'mysqlval_8');
INSERT INTO T_MYSQL(id, val) value (9, 'mysqlval_9');
INSERT INTO T_MYSQL(id, val) value (10, 'mysqlval_10');



linkedtestというデータベースにT_MYSQLというテーブルを作成。
適当にサンプルのデータをインサートしました。







MySQLのJDBCドライバ



LINKED TABLEを使うには、別データベースに接続するためJDBCドライバが必要なようです。
今回はMySQLとLINKED TABLEしてみるので、MySQLのJDBCドライバをダウンロードしました。

http://dev.mysql.com/downloads/connector/j/
ここからmysql-connector-java-5.1.18.tar.gzをダウンロードして解凍し、
mysql-connector-java-5.1.18-bin.jarを取得します。







H2起動時のclasspath指定



H2はDebianで動かしています。
環境はここで作成した時と同様。
DebianでH2 Database Engineを起動し、別端末からJavaで接続する

/opt/h2/binにh2-1.3.162.jarがある状態です。

MySQLのサイトからダウンロードして取得したmysql-connector-java-5.1.18-bin.jarを
/opt/h2/libにコピーしました。

このコピーしたjarをクラスパスに含めて、H2を起動します。
起動するときのオプションはこんな感じ。


# java -cp h2-1.3.162.jar:/opt/h2/lib/mysql-connector-java-5.1.18-bin.jar
    org.h2.tools.Server -webAllowOthers -tcpAllowOthers -baseDir /opt/h2/data


※実際は一行。Windowsの場合は、-cp以降のjarファイルの区切り文字が「;」になるかと思います。


これで準備は完了です。






Javaのサンプルプログラム



別端末からJavaのプログラムで接続してLINKED TABLEを作成し、検索してみます。

なお、LINKED TABLEを作成する時の構文は



CREATE LINKED TABLE [H2内で使用するテーブル名]('[JDBCドライバクラス]', '[接続文字列]', '[ユーザー名]', '[パスワード]', '[リンクするテーブル名]');



そのため、今回MySQLに作成したlinkedtestデータベースのT_MYSQLテーブルを
T_LINKという名称でLINKED TABLEにするには


CREATE LINKED TABLE T_LINK
('com.mysql.jdbc.Driver', 'jdbc:mysql://localhost/linkedtest',
'[MySQLのユーザー名]', '[MySQLのパスワード]', 'T_MYSQL')


となりまkす。


これらを踏まえ、
・MySQLとT_LINKというLINKED TABLEを作成
・H2にT_H2というテーブルを作成
・T_LINK(MySQLのテーブル)とT_H2(H2のテーブル)を結合し、検索結果表示
というサンプルはこんな感じになりました。

※実行するクライアントにMySQLのJDBCドライバは不要です。
H2のJDBCドライバだけあればOK




package com.fc2.blog68.symfoware.h2;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class SampleLinked {
    public static void main(String[] args) throws Exception {
        
        //JDBCドライバをロード
        Class.forName("org.h2.Driver");
        
        //コネクション取得
        Connection conn = DriverManager.getConnection("jdbc:h2:tcp://192.168.1.4/test", "sa", "");
        Statement stmt = conn.createStatement();
        
        //テーブル作成
        stmt.execute("CREATE TABLE IF NOT EXISTS T_H2 (id integer, val varchar(20))");
        stmt.execute("DELETE FROM T_H2");
        
        
        //データの登録
        stmt.execute("INSERT INTO T_H2 (id, val) values (1, 'h2val_1')");
        stmt.execute("INSERT INTO T_H2 (id, val) values (2, 'h2val_2')");
        stmt.execute("INSERT INTO T_H2 (id, val) values (3, 'h2val_3')");
        stmt.execute("INSERT INTO T_H2 (id, val) values (4, 'h2val_4')");
        stmt.execute("INSERT INTO T_H2 (id, val) values (5, 'h2val_5')");
        stmt.execute("INSERT INTO T_H2 (id, val) values (6, 'h2val_6')");
        stmt.execute("INSERT INTO T_H2 (id, val) values (7, 'h2val_7')");
        stmt.execute("INSERT INTO T_H2 (id, val) values (8, 'h2val_8')");
        stmt.execute("INSERT INTO T_H2 (id, val) values (9, 'h2val_9')");
        stmt.execute("INSERT INTO T_H2 (id, val) values (10, 'h2val_10')");
        
        //リンクテーブル作成
        stmt.execute("CREATE LINKED TABLE T_LINK('com.mysql.jdbc.Driver', 'jdbc:mysql://localhost/linkedtest', 'root', 'password', 'T_MYSQL')");
        
        //登録したデータの検索
        StringBuffer sql = new StringBuffer();
        sql.append("SELECT");
        sql.append(" T_H2.id AS H2_ID,");
        sql.append(" T_H2.val AS H2_VAL,");
        sql.append(" T_LINK.id AS MYSQL_ID,");
        sql.append(" T_LINK.val AS MYSQL_VAL");
        sql.append(" FROM");
        sql.append(" T_H2, T_LINK");
        sql.append(" WHERE");
        sql.append(" (T_H2.id = T_LINK.id)");
        
        ResultSet rs = stmt.executeQuery(sql.toString());
        while(rs.next()) {
            System.out.print(rs.getString("H2_ID") + " : ");
            System.out.print(rs.getString("H2_VAL") + " : ");
            System.out.print(rs.getString("MYSQL_ID") + " : ");
            System.out.println(rs.getString("MYSQL_VAL"));
        }
        
        stmt.close();
        conn.close();
        
    }
}






実行してみると、ちゃんとMySQLの表とH2の表の結合結果が表示されます。

1 : h2val_1 : 1 : mysqlval_1
2 : h2val_2 : 2 : mysqlval_2
3 : h2val_3 : 3 : mysqlval_3
4 : h2val_4 : 4 : mysqlval_4
5 : h2val_5 : 5 : mysqlval_5
6 : h2val_6 : 6 : mysqlval_6
7 : h2val_7 : 7 : mysqlval_7
8 : h2val_8 : 8 : mysqlval_8
9 : h2val_9 : 9 : mysqlval_9
10 : h2val_10 : 10 : mysqlval_10






もちろん、

stmt.execute("INSERT INTO T_LINK(id, val) values (11, 'mysqlval_11')");


として、MySQLのテーブルにデータの追加、更新も可能です。

これ、複数のデータベースが混在している環境で上手く使えば、強力な機能かも。


テーマ:データベース - ジャンル:コンピュータ

  1. 2011/12/06(火) 23:08:58|
  2. H2 Database Engine
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

H2 Database EngineにPythonから接続する(psycopg使用)

PostgresqlのJDBCドライバを使用して、H2 Database Engineに接続してみました。
H2 Database Engineに、PostgresqlのJDBCドライバでJavaで接続する


ということは、Postgresqlに接続するためのライブラリがあれば
どんな言語からも接続できるはず。

ということで、Pythonからpsycopgを使用して接続してみました。
http://initd.org/psycopg/install/




psycopgのインストール



Ubuntuにpsycopgをインストールします。
まず、ビルドに必要となるライブラリをインストール。


$ sudo apt-get install python-dev libpq-dev




easy_installを使ってインストールするので、setuptoolsをインストール


$ sudo apt-get install python-setuptools




psycopg2をインストール


$ sudo easy_install psycopg2




これでpsycopgのインストールは完了です。







saのパスワード設定



H2 Database Engineに接続するとき、ユーザー「sa」、パスワード空白が
初期値で設定されています。

psycopg2で接続するとき、パスワードに空白を指定すると

Traceback (most recent call last):
    File "sample.py", line 5, in <module>
    con = psycopg2.connect(database="test", user="sa", host = "192.168.1.4", port = 5435, password="")
psycopg2.OperationalError: fe_sendauth: no password supplied


こんな感じで、空白は指定できないというエラーが発生します。


そのため、Webの管理画面からパスワードの設定を行いました。

実行するクエリは以下のとおり。


SET PASSWORD 'Passw0rd'



05_001_20111206214437.png



これで接続しているユーザー(この場合はsaでログインしているのでsa)にパスワードが設定されます。







Pythonのサンプルプログラム



サンプルプログラムはこんな感じになりました。


# -*- coding:utf-8 -*-
import psycopg2
import psycopg2.extras

con = psycopg2.connect(database="test", user="sa", host = "192.168.1.4", port = 5435, password="Passw0rd")
cur = con.cursor(cursor_factory=psycopg2.extras.DictCursor)
cur.execute("SELECT * FROM test")

rec = cur.fetchone()
print rec['name']

cur.close()
con.close()





実行してみると、ちゃんとJavaから登録したデータが得られます。


$ python sample.py
日本語テスト



テーマ:データベース - ジャンル:コンピュータ

  1. 2011/12/06(火) 21:45:00|
  2. H2 Database Engine
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

H2 Database Engineに、PostgresqlのJDBCドライバでJavaで接続する

H2 Database Engineのサイトを見てみると・・・
http://www.h2database.com/html/advanced.html

Postgresqlのプロトコルに対応しているみたいです。


DebianでH2 Database Engineを起動し、別端末からJavaで接続する
ここでH2のJDBCでの接続は試しました。
今回はPostgresqlのJDBCドライバを使用して接続してみます。




H2 Database Engineの起動モードの変更



外部からJDBC接続を行うため、H2を起動するとき、

# java -cp h2-1.3.162.jar org.h2.tools.Server -webAllowOthers -tcpAllowOthers


こんな感じで、「-tcpAllowOthers」というオプションをつけて
外部からのTCP接続を許可しました。

これは、H2 JDBCでの接続を許可するという意味です。
Postgresqlのプロトコルで外部接続を許可するには、
「-pgAllowOthers」
というオプションを付けて起動してやる必要があります。




/opt/h2/bin# java -cp h2-1.3.162.jar org.h2.tools.Server -webAllowOthers -tcpAllowOthers -pgAllowOthers
Web Console server running at http://127.0.1.1:8082 (others can connect)
Failed to start a browser to open the URL http://127.0.1.1:8082: Browser detection failed and system property h2.browser not set
TCP server running at tcp://127.0.1.1:9092 (others can connect)
PG server running at pg://127.0.1.1:5435 (others can connect)



「PG server running at pg://127.0.1.1:5435」以降の表示が
(only local connections)
ではなく、
(others can connect)
であれば、外部からの接続を受け入れる状態で起動していることになります。



追加で、データベースファイルを保存する位置を明確にしたかったので、
「-baseDir [保存先のパス]」
というオプションを付けて起動することにしました。

ファイルの保存先を「/opt/h2/data」とすることにします。


# mkdir /opt/h2/data



として、ファイルの保存先のディレクトリを作成した上で


# java -cp h2-1.3.162.jar org.h2.tools.Server
-webAllowOthers -tcpAllowOthers -pgAllowOthers -baseDir /opt/h2/data


※実際は一行

というコマンドで、H2を起動しておきます。








PostgresqlのJDBCドライバをダウンロード



結構前の話になりますが、PostgresqlにJDBCドライバ経由で接続したことがあります。
DebianのPostgresqlに別の端末からJDBCで接続する

ここを参考に、サンプルプログラムを作成することにしました。


まず、PostgresqlのJDBCドライバをダウンロード
http://jdbc.postgresql.org/download.html

ここから最新版の「JDBC4 Postgresql Driver, Version 9.1-901」をダウンロードし、
サンプルプログラムを作成します。

なお、Postgresqlでは接続にポート番号5432を使用しますが、
H2にはポート番号5435で接続します。

ユーザーは「sa」、パスワード空白です。



package com.fc2.blog68.symfoware.h2;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class SamplePG {
    
    public static void main(String[] args) throws Exception {
        //JDBCドライバのロード
        Class.forName("org.postgresql.Driver");
        
        //接続
        String url = "jdbc:postgresql://192.168.1.4:5435/test";
        Connection con = DriverManager.getConnection(url, "sa", "");
        
        Statement stmt = con.createStatement();
        
        ResultSet rs = stmt.executeQuery("SELECT * FROM TEST");
        
        while(rs.next()) {
            System.out.println(rs.getString("NAME"));
        }
        rs.close();
        stmt.close();
        
        con.close();
    }
    
}





実行してみるとあえなく撃沈。

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
    at java.util.ArrayList.rangeCheck(ArrayList.java:571)
    at java.util.ArrayList.get(ArrayList.java:349)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1899)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:510)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:372)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:252)




データベースへの接続は行えているのですが、SELECTを実行した時に
エラーが発生してしまいます。






Postgresql - JDBCドライバのバージョン



動かないはずはないと思って調べてみると、どうやら使用するPostgresqlのJDBCドライバの
バージョンによってはデータの取得が行えることが分かりました。

postgresql-8.2-512.jdbc4.jar:OK
postgresql-8.3-607.jdbc4.jar:OK
postgresql-8.4-703.jdbc4.jar:NG
postgresql-9.1-901.jdbc4.jar:NG

8.3から8.4で、大きな仕様変更が入っているようです。


postgresql-8.3-607.jdbc4.jarを使用し、プログラムを実行してみると



日本語テスト




素っ気ないですが、ちゃんとH2のJDBCドライバを使用して登録した
データを検索することができました。


ちなみに、H2はODBCドライバを提供していないのですが、Postgresql用の
ODBCドライバを使用すれば、接続できるとのこと。

ODBCドライバでも、使用するバージョンによって同様の現象が発生するのかもしれません。






テーマ:データベース - ジャンル:コンピュータ

  1. 2011/12/06(火) 20:32:10|
  2. H2 Database Engine
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
次のページ