Quantcast
Channel: データベース –俺的備忘録 〜なんかいろいろ〜
Viewing all 33 articles
Browse latest View live

MS Office Accessのサイズが2GBを超えてしまったときの対処法

$
0
0

※このページは2013/12/18に大幅に書き換えています。

仕事、特にオフィスワークをしているとDBとの関わり無しでは仕事にならない。

大規模システムから小規模なデータのまとめだったりと様々です。もちろん、大規模システムからデータを抽出し、欲しいデータに加工することだってあるだろう。
そういった意味で、MS OfficeのAccessはお手軽にデータベースを構築でき、DB初心者にも扱いやすく、リンクテーブルを使用すれば大規模システムのDBクライアントにもなるし少し工夫すれば小規模WEBシステムのDBにも出来るツールのため、使っている方も多いだろう。
そんなAccessだが、かなり厄介な制限がある。Accessのファイル形式「.mdb(Office 2007以降の場合は.accdb)」の容量上限が約2GBであるという点だ。
それは、Accessファイルの容量は「MS Office 2003」はもちろん、今後導入されることが多くなるであろう「MS Office 2010」であっても変わらない。おそらく、ファイル拡張子が2007以降と同じ「MS Office 2013」でも変わらないだろう。過去のバージョンと互換性が失われてしまうからだ。

そもそも、通常のRDBMSは一つないし複数のテーブルごとに一個の物理ファイルとして作成し、それら複数の物理ファイルを一つのデータベースとして扱う方式。たとえ一つのテーブルが一定以上の容量になったとしても、ある程度自動的にテーブルを分割するため、2GB程度で容量オーバーになることは無い。

しかし、Accessの場合はファイル「.mdb(.accdb)」にすべてのテーブルを格納してしまう。

20131217_001

今どきのファイルシステムであれば、1ファイル2GB以上のデータは簡単に作れる。ただ、過去のしがらみか(Windows 95とか98の際には、ファイルシステムにFAT16というものが使われていて、これは2GB以上のファイルが作成出来なかった。)自社のSQL Serverを入れたいためかは不明だが「.mdb(.accdb)」形式では2GB以上のデータは作れない。2GBを超えてしまうと「引数が無効です」というエラーが表示されてしまい、それ以降内部データを削除するまではデータの追加ができなくなる。

このようなエラーが起きると、その後の作業が止まってしまう。10年程度前であれば、Accessで2GB以上のデータを使うことなんて稀だったのかもしれない。しかし、今の時代、2GB程度で止まってしまうのは困る。

とはいえAccessにこのような制限があるのは事実なので、これとうまく付き合っていき、かつ対応する方法を記述する。

1.応急処置で「データベースの最適化/修復」を行う

RDBMSではおなじみとも言える作業。そもそも、Accessのテーブルにあるデータを消したといってもすぐにAccessのサイズが小さくなるわけではない。

ただ削除しただけだと、データはいぜん「.mdb(.accdb)」ファイル内に残り続け、認識されるファイルサイズは変動しない。

そこで、「削除を適用させる(ファイルサイズに反映させる)」ために、「データベースの最適化/修復」という作業を行う事で、「.mdb(.accdb)」ファイルと内部のデータとを連携させる事が出来る。

図:Accessの容量変動イメージ

20131217_002

「データベースの最適化/修復」の方法は2003の場合はこっち、2010の場合はこのページに掲載されている。

で、当たり前なんだけど、この方法はあくまでもAccessの容量と格納されているテーブルの容量に乖離があるときにしか使えない訳で、テーブルの容量が大きい場合にはこの方法では対処不可能になる。

2.Accessを分割する

要は、Accessが1ファイルごとに2GB以上の場合に問題が出るわけなのだから、複数ファイルに分けてしまえばいいということ。

20131217_003

物理的にAccessファイルを分割し、互いの連携を「リンクテーブル」というAccessの機能で行う事で対応するというもの。

これなら、Accessで作成されていたクエリも、一部以外は使い回す事が可能となる。ここでいう一部だが、テーブル更新・削除クエリ(テーブル内部のみ削除するクエリの事。紛らわしい名前…)は使い回し可能だが、テーブル追加クエリでTableA.accdbやTableB.accdbにテーブルの追加ができないため、対策が別途必要になる。

なぜかというと、リンクテーブルという機能は「Access」へのリンクを作るのではなく、「テーブル」へのリンクのためである。つまり、リンクをする対象となるテーブルをリモートで作成することが出来ない。

さらにもう一つ、根本的な問題がある。それは、テーブル1個の容量が2GBを超える場合には対応できない。

3.別のRDBMSシステムを使用し、クライアントとしてAccessを利用する。

そんなことわかってるんだよ!

と言われそうな気がする。

といっても、わざわざDBサーバを起動させるようなやり方ではない。
RDBMSの中に「SQLite」というものがある。このシステム、Accessと同じように1ファイルにテーブルデータ等を保持する形式となっているのだが、容量制限が32TBまでとなっている。これをリンクテーブル先にすればよいのだ。

実際の作業方法は以下のページを参照してもらうとわかりやすい。

AccessからSQLiteのデータベースを使用する方法
http://www.crystal-creation.com/software/tool/office/access/external/sqlite.htm

MSAccessからSQLiteを操作する
http://atm-tkd.sakura.ne.jp/pcspe/sqlite/sqlite09access.php

Accessでaccdbを使わずに他のDBを使ってみる ? SQLite編1
http://foolexp.wordpress.com/2012/06/20/access%E3%81%A7accdb%E3%82%92%E4%BD%BF%E3%82%8F%E3%81%9A%E3%81%AB%E4%BB%96%E3%81%AEdb%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B-sqlite%E7%B7%A81/



もちろん、SQLiteを使用するにもデメリットが存在する。上の3つ目のリンクに乗っているんだけど、処理が遅いということ。

現時点では、Accessの2GB制限は解除されることは無く、その方法も無い。
うまいこと工夫してやりくりするしか無いというのが現状。

追記
他のDBソフトで代用できないか、少し調べてみました。


MS Office Accessのサイズが2GBを超えてしまったときの対処法 ~Access以外のDB管理ソフト検証~

$
0
0

以前、MS Office Accessが2GBを超えてしまった場合における対処方法について記述していたが、その続き。

前回は、2GB以上の「.mdb(.accdb)」ファイルを作成する方法は存在しない事から、いかに容量を2GB以内におさめるかに注力していた。

このあたりについては、英語圏の人たちも苦労している事が伺える。以下にその一例を。

Microsoft Access Specifications and Limitations

http://webcheatsheet.com/sql/access_specification.php

Access MDB: do access MDB files have an upper size limit?

http://stackoverflow.com/questions/2785851/access-mdb-do-access-mdb-files-have-an-upper-size-limit

今回は、もうそもそもAccessでは2GB以上使えないと諦めてMS Office Accessに変わるデータベースソフトウェアを検証してみることにした。

対象は、以下の観点で選定した。

  • 2GB以上のファイルとして扱えるか否か
  • 別途データベースサーバを立てる必要が無いか(単一ファイルで作業が可能か)
  • SQLに(そこまで)明るくない人間でも操作出来るか

まぁ、3点目はそこまで重視していない。わかんなければ勉強してもらえれば…SQLなんてそんな難しくないし…

Libre Office

OfficeソフトウェアでMS Office以外とくればまず名前が上がる「Libre Office」のデータベースソフトウェア「Base」で対応が出来ないかを検証してみた。

まずは下調べから。Libre Office Baseのファイル最大容量はいくらなのかを確認。
以下のページを参照してみた。

Limit on Base records? | LibreOfficeForum.org

http://en.libreofficeforum.org/node/4288

上記を確認すると、Libre Office Baseのデータベースは「HSQLDB」というRDBMSを使用しており、貼られている英語版のWikipediaのページを見るとその最大容量は64TBとのこと。

つまり、2GB以上のファイルは作成出来るということになる。

でLibre Office 4.1をちょっと触ってみた結果…

  1. 重くて使い物にならない
  2. ユーザビリティが低すぎる(CSVからのインポート等が複雑)
  3. Javaが必須
  4. Baseが落ちるとその他のLibre Office系ソフトウェアも一緒に落ちる

具体的に言うと、1は言わずもがな。重くて重くて、とても使えたものではない。5000件程度のデータをインポートするのに5~10分はかかり、その間Baseはおろか、Clac等も触れない。Core i5を使っているにも関わらず、すさまじい重さ…

結局、あまりにもレスポンスが重いので3MB程度で検証は断念。

2もひどく、Accessでは簡単に行えるCSV等からのインポートには、一度CSVファイルをClacで読み込んだ上で、テーブルに貼り付け(重い)するか、Baseで新規データベースとして扱って内容を取り込むしか無い(これも重い)。

更に、外部データからインポートして作成したテーブルの一部は、編集が出来ないようになっているようだ。(CSVファイルからインポートしたテーブル。3度ほど確認したが事象再現できた。)

3、4はまぁいいとしても(良くないけど)、上記2点によって個人的には使い物にはならないと思う。
この重さは万国共通なんだろうか?それとも、単に自分のPCの環境や設定が悪かったからなんだろうか…

一応、JA福岡市の方がマニュアルを公開しているので紹介。

「LibreOffice_Base用マニュアル」を公開いたしました。

http://www.ja-fukuoka.or.jp/libre/2332/

なお、派生元であるOpenOfficeについてはLibre Officeと大して変わらないと思われるので、検証しないものとする。

SQLite(+PupSQLite)

以前にもAccessの2GBを超えた際の対処案として出していたが、やはりSQLiteは扱ってみようと思う。

しかし、AccessをSQLiteのクライアントとして使う場合はODBCの設定等が必要となり、更に新規テーブルをAccess経由で作成出来ない事から、既存のテーブルを使いまわす業務が中心になってしまう。

そこで、GUIでSQLiteを扱えるフリーソフトのうち、CSV等からSQLiteへインポートが可能という「PupSQLite」を検証して見ることにした。

なお、事前に注意したいのが以下に該当する人はこの方法ではなく、SQLite(+MS Office Access+その他SQLiteクライアント)の手段を取る事をおすすめする。

  • SQLなんて全くわからないし、勉強する時間も無い
  • 既存のAccessの追加、更新、削除クエリをそのまま使いまわしたい

理由は、本ソフトウェアに限らずこういったデータベースクライアントはAccessでいう更新クエリといったものはなく、更新を行うためのSQL文は自分で作成し、別途.sqlファイルとして保存する必要があるからである。

そのため、SQLをある程度理解していて、既存のクエリを書き直すことが出来る人間であればこのツール一個で対応できるが、そうでないのであればこれに加え、クライアントにAccessを使用する方式をとったほうが良い。

では、まず以下からクライアントソフトウェアをダウンロード。

Pup’s Atelier-Software

http://www.eonet.ne.jp/~pup/software.html

※なお、上記ページにも記述されているがこのソフトウェアは.Net Fream Workが必要なので事前にインストールする必要がある。

このソフトはインストールせずに使用するタイプなので、上記ページからzipファイルをダウンロードして解凍すると、実行ファイル「PupSQLite.exe」があるのでダブルクリック。

実行すると、以下のような画面が表示されるので、上部メニューより「データベースの新規作成」をクリック。

新規にデータベースを作成する場合、まずテーブルを作るように言われるので、そのテーブル名を入力。

テーブルの新規作成画面。

CSVからファイルをインポートしてみる。
上部メニューから「ファイルからインポート」を選択

インポートするファイル、インポート先のデータベースを選択する。
ここではkazina.comさんの「なんちゃって個人情報」から5,000件ほどのデータを作成してインポートしてみた。

テーブルの新規作成画面。今回はこのまま「OK」をクリック。

インポートが開始される。
5,000件程度ならば1分もかからずに完了する。

自動生成後、テーブルに登録されたニセ個人情報。

次にビュー。Accessで言うと(ある意味)参照クエリに当たるもの、と考えてもらえるとわかりやすい。

抽出条件にビューの結合条件を記述する。
このツールではあくまでも通常のInner Joinしか出来ないため、細かい指定をする場合は「SQL文確認」から手打ちで修正する。

なお、ビューの作成以降はSQLを修正出来ないので、間違えない用に注意すること。

簡単な使い方は以上。
OracleやPostgresql、MySQLを使った事のある人ならばすぐに使えるようになるのではないだろうか。

(とは言え、今までAccessしか使ったことが無いような人には難しいかもしれない…)

なおSQLiteと本ソフトウェアに加え、今までのAccessを使いたい場合はクライアントPC(Accessを実行するパソコン)でODBCの設定を行い、SQLiteのテーブルをリンクテーブルとして使えばいいだろう。

SQLite側でテーブルが必要になる場合は、上記ツールを使用して別途作成すればいい。

ODBCでSQLiteを参照する方法は、以下のページを参考にすると良い。

AccessからSQLiteのデータベースを使用する方法

http://www.crystal-creation.com/software/tool/office/access/external/sqlite.htm

しかし、そろそろAccessの容量制限も解除出来ないものだろうか?
フリーウェアで2GBなんて存在していないんだし、技術的には可能だと思うんだけど…

CentOS 7にMongoDBをインストールする

$
0
0

通常、データベースというとRDBMSをイメージすると思うが、このMongoDBはRDBMSではなく、いわゆるNoSQLと呼ばれるものだ。
以下、Wikipediaから引用。

MongoDBはRDBMSではなく、いわゆるNoSQLと呼ばれるデータベースに分類されるものである。RDBMSのようにレコードをテーブルに格納するのではなく、「ドキュメント」と呼ばれる構造的データをJSONライクな形式で表現し、そのドキュメントの集合を「コレクション」として管理する(このデータの物理的な格納はBSONと呼ばれるJSONのバイナリ版といえる形式で行われる)。コレクションはRDBMSのような固定的なスキーマを持たない。ドキュメントには複雑な階層構造を持たせることもでき、それらの構造に含まれるフィールドを指定したクエリやインデクス生成も簡単な指定によって行える。RDBMSのように高度な結合操作を効率的に行うことはできないが、データの追加・更新・削除・クエリは高速に行うことができる。また、アプリケーションは自身の構造やデータ型に合った自然な形でデータを格納することができるため、扱うデータの特性によっては、RDBMSよりも容易かつ迅速に開発を行うことができる可能性がある。
Mongoという名前は、英語で「ばかでかい」を意味する “humongous” に由来する。
MongoDBの開発は10gen(現MongoDB Inc.)によって2007年10月から開始され、最初の公開リリースは2009年2月に行われた。

さて、今回はこのMongoDBをCentOS 7にインストールしてみる。

1.インストール

CentOS 7にMongoDBをインストールするために、まずはMongoDBのYumレポジトリを追加する。
「/etc/yum.repos.d/mongodb.repo」というファイルを作成する。

vi /etc/yum.repos.d/mongodb.repo

記述する内容配下。

[mongodb]
name=MongoDB repo
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/
gpgcheck=0
enabled=1

 

レポジトリファイルの作成が完了したら、以下のコマンドでMongoDBをインストールする。

yum install mongodb-org

20141205_000000

 

以下、出力例。

[root@localhost ~]# yum install mongodb-org
読み込んだプラグイン:fastestmirror
mongodb                                                          |  951 B  00:00:00
mongodb/primary                                                  |  37 kB  00:00:01
Loading mirror speeds from cached hostfile
 * base: ftp.tsukuba.wide.ad.jp
 * epel: ftp.tsukuba.wide.ad.jp
 * extras: ftp.tsukuba.wide.ad.jp
 * updates: ftp.tsukuba.wide.ad.jp
mongodb                                                                         240/240
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ mongodb-org.x86_64 0:2.6.5-1 を インストール
--> 依存性の処理をしています: mongodb-org-shell = 2.6.5 のパッケージ: mongodb-org-2.6.5-1.x86_64
--> 依存性の処理をしています: mongodb-org-server = 2.6.5 のパッケージ: mongodb-org-2.6.5-1.x86_64
--> 依存性の処理をしています: mongodb-org-mongos = 2.6.5 のパッケージ: mongodb-org-2.6.5-1.x86_64
--> 依存性の処理をしています: mongodb-org-tools = 2.6.5 のパッケージ: mongodb-org-2.6.5-1.x86_64
--> トランザクションの確認を実行しています。
---> パッケージ mongodb-org-mongos.x86_64 0:2.6.5-1 を インストール
---> パッケージ mongodb-org-server.x86_64 0:2.6.5-1 を インストール
---> パッケージ mongodb-org-shell.x86_64 0:2.6.5-1 を インストール
---> パッケージ mongodb-org-tools.x86_64 0:2.6.5-1 を インストール
--> 依存性解決を終了しました。

依存性を解決しました

========================================================================================
 Package                     アーキテクチャー
                                             バージョン          リポジトリー      容量
========================================================================================
インストール中:
 mongodb-org                 x86_64          2.6.5-1             mongodb          4.6 k
依存性関連でのインストールをします:
 mongodb-org-mongos          x86_64          2.6.5-1             mongodb          6.8 M
 mongodb-org-server          x86_64          2.6.5-1             mongodb          9.0 M
 mongodb-org-shell           x86_64          2.6.5-1             mongodb          4.3 M
 mongodb-org-tools           x86_64          2.6.5-1             mongodb           89 M

トランザクションの要約
========================================================================================
インストール  1 パッケージ (+4 個の依存関係のパッケージ)

総ダウンロード容量: 109 M
インストール容量: 276 M
Is this ok [y/d/N]: y
Downloading packages:
(1/5): mongodb-org-2.6.5-1.x86_64.rpm                            | 4.6 kB  00:00:00
(2/5): mongodb-org-mongos-2.6.5-1.x86_64.rpm                     | 6.8 MB  00:00:06
(3/5): mongodb-org-server-2.6.5-1.x86_64.rpm                     | 9.0 MB  00:00:07
(4/5): mongodb-org-shell-2.6.5-1.x86_64.rpm                      | 4.3 MB  00:00:06
(5/5): mongodb-org-tools-2.6.5-1.x86_64.rpm                      |  89 MB  00:00:51
----------------------------------------------------------------------------------------
合計                                                       1.8 MB/s | 109 MB  01:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  インストール中          : mongodb-org-server-2.6.5-1.x86_64                       1/5
  インストール中          : mongodb-org-shell-2.6.5-1.x86_64                        2/5
  インストール中          : mongodb-org-tools-2.6.5-1.x86_64                        3/5
  インストール中          : mongodb-org-mongos-2.6.5-1.x86_64                       4/5
  インストール中          : mongodb-org-2.6.5-1.x86_64                              5/5
  検証中                  : mongodb-org-mongos-2.6.5-1.x86_64                       1/5
  検証中                  : mongodb-org-tools-2.6.5-1.x86_64                        2/5
  検証中                  : mongodb-org-shell-2.6.5-1.x86_64                        3/5
  検証中                  : mongodb-org-2.6.5-1.x86_64                              4/5
  検証中                  : mongodb-org-server-2.6.5-1.x86_64                       5/5

インストール:
  mongodb-org.x86_64 0:2.6.5-1

依存性関連をインストールしました:
  mongodb-org-mongos.x86_64 0:2.6.5-1        mongodb-org-server.x86_64 0:2.6.5-1
  mongodb-org-shell.x86_64 0:2.6.5-1         mongodb-org-tools.x86_64 0:2.6.5-1

完了しました!

 

2.MongoDBの有効化&起動

次に、MongoDBをOS起動時に自動起動するようにし、かつサービスを起動させる。
なお、MongoDBはsystemctlでの有効化は出来ないため、chkconfigでの有効化を行う。

chkconfig  mongod  on

 

さらに、以下のコマンドでMongoDBのサービスを手動起動させる。

systemctl start mongod

20141205_000003

さて、それでは実際にMongoDBにアクセスしてみよう。
以下のコマンドを実行する。

mongo

20141205_000005

無事、アクセスできることを確認した。

 

3.ファイアウォールの設定変更

最後に、ファイアウォールの設定で27017ポートを開放する。

firewall-cmd --zone=public --add-port=27017/tcp --permanent
firewall-cmd --reload

20141205_000004

これで、外部からMongoDBへ接続出来るようになった。

NOSQLの基礎知識 (ビッグデータを活かすデータベース技術) NOSQLの基礎知識 (ビッグデータを活かすデータベース技術)

 

HeidiSQLでWindowsからMySQLサーバにSSH経由で接続する

$
0
0

WindowsからMySQLサーバにクライアントソフトを用いてアクセスする場合、通常はMySQLデータベース側でリモートアクセスの許可をしておく必要がある。
しかし、外部からの接続を許可していないMySQLにクライアントソフトからアクセスしたい時もあるだろう。そんなときは、MySQLにSSHを経由してログインするMySQLクライアントソフトを用いるとよい。

今回は、そんなSSH経由でMySQLを操作することができるクライアントソフト『HeidiSQL』で、SSH経由でMySQLに接続、操作を行う手順を説明する。

1.HideiSQLのインストール

まずは、HideiSQLのダウンロード、インストールを行う。
こちらのリンク先から好きなバージョン(とりあえず、最新版で良いだろう)のインストーラーをダウンロードし、インストーラーを起動する。

20150118-000010

インストーラーは、基本的に「次へ」を押し続けていくだけなので説明は割愛する。

2.HideiSQLにMySQLへの接続設定を行う

次に、インストールしたHideiSQLに対して、接続先となるMySQLサーバの情報を設定する。
まずは[新規] > [セッションを追加]を選択し、新規のセッションを作成する。

20150118-000013

新規のセッションが作成できたら、任意の名称に変更する。
右カラムから[設定]タブを開き、[MySQL(SSH tunnel)]を選択し、「SSH接続後にMySQLに接続する際の情報」を記述する。

20150118-000014

20150118-000015

ここでポイントになるのが、この設定は今HeidiSQLをインストールしたマシンから見た接続情報ではなく、SSH接続先から見た接続情報だということ。
つまり、SSHで直接MySQLサーバにアクセスするようであれば、ここの接続先はMySQLサーバから見て自分自身となる「127.0.0.1(localhost)」となる。

次に、SSHトンネル設定を行う。
SSHトンネルを利用する際は、「plink.exe」というプログラムが必要となる。もしまだプログラムをダウンロードしていない場合は、[plink.exeの場所]の下にある[plink.exeをダウンロードする]からダウンロードし、適当な場所に設置する。ファイル設置後、[plink.exeの場所]でファイルパスを指定する。ここでは、HeidiSQLの設置場所である「C:\Program Files\HeidiSQL」配下に設置する。

その他、SSH接続で必要になるSSH接続先のホスト名やポート、ID、パスワードを指定する。
更に、デフォルトのタイムアウト値が4秒と少なすぎるため、10秒~30秒程度に変更する。

20150118-000018

これで、セッションの設定が完了したので、左下の[保存]をクリックする。

3.known_hostとして登録する

セッションの設定完了後、すぐに接続出来るわけではない。
接続先をknown_hostとして登録するため、一度手動でplink.exeを使ってSSH接続を行う必要がある。
そのため、コマンドプロンプトで以下のコマンドを実行する。

"C:\Program Files\HeidiSQL\plink.exe" ユーザ名@SSHホスト名
C:\Users\Work>"C:\Program Files\HeidiSQL\plink.exe" ユーザ名@SSHホスト名
The server's host key is not cached in the registry. You
have no guarantee that the server is the computer you
think it is.
The server's rsa2 key fingerprint is:
ssh-rsa 2048 4X:07:XX:7b:8f:21:XX:f6:ey:1c:XX:3e:6e:c7:XX:fa
If you trust this host, enter "y" to add the key to
PuTTY's cache and carry on connecting.
If you want to carry on connecting just once, without
adding the key to the cache, enter "n".
If you do not trust this host, press Return to abandon the
connection.
Store key in cache? (y/n)

「Store key in cache? (y/n) 」という表示がされたら、「y」を選択する。
これで、known_hostとしてレジストリに登録がされた。

4.MySQLに接続する

これでHeidiSQLでMySQLに接続ができるようになった。
セッションの[開く]を選択する。

20150118-000020

20150118-000021

無事、MySQLサーバにアクセスすることが出来た。
使用するデータベースが制限されているなら、接続時の情報にデータベースを指定してあげると良いだろう。

MariaDB&MySQL全機能バイブル MariaDB&MySQL全機能バイブル

CentOS 7にPostgreSQL9.4のインストールを行う

$
0
0

そろそろデータベース、できればOSSのものを扱えるようになりたいなぁ…と思ったので、CentOS 7 にPostgreSQLを入れてみることにした。
今回は、とりあえずインストールとサービスの起動までを行う。

1.インストール

まずはインストールから。
yumを利用出来る環境なのであれば、以下のようにコマンドを実行することでPostgreSQLリポジトリの追加、パッケージのインストール出来る。

●PostgreSQL 9.4の場合

yum install http://yum.postgresql.org/9.4/redhat/rhel-7-x86_64/pgdg-redhat94-9.4-1.noarch.rpm
yum groupinstall "PostgreSQL Database Server 9.4 PGDG"

 

9.3以前の場合は、利用するリポジトリが違うので注意する。

rpmパッケージなどからインストールする場合は、こちらから必要なrpmパッケージをダウンロードしてインストールすると良いだろう。
普通にrpmコマンドからインストールすると手間なので、「yum localinstall」でインストールすると楽だろう。

2.サービスの起動

次に初期設定を行う。
まず最初に、クラスタの初期化を行う。このコマンドを実行せずにサービスを起動した場合、以下のようなエラーが出てサービスが起動しないので注意する。

[root@test-centos7 ~]# systemctl start postgresql-9.4
Job for postgresql-9.4.service failed. See 'systemctl status postgresql-9.4.service' and 'journalctl -xn' for details.

 

以下のコマンドを、rootユーザで実行する。

/usr/pgsql-9.4/bin/postgresql94-setup initdb
[root@test-centos7 ~]# /usr/pgsql-9.4/bin/postgresql94-setup initdb
Initializing database ... OK

[root@test-centos7 ~]# systemctl start postgresql-9.4
[root@test-centos7 ~]# systemctl status postgresql-9.4
postgresql-9.4.service - PostgreSQL 9.4 database server
   Loaded: loaded (/usr/lib/systemd/system/postgresql-9.4.service; disabled)
   Active: active (running) since 金 2015-05-29 07:21:01 JST; 29s ago
  Process: 9239 ExecStart=/usr/pgsql-9.4/bin/pg_ctl start -D ${PGDATA} -s -w -t 300 (code=exited, status=0/SUCCESS)
  Process: 9233 ExecStartPre=/usr/pgsql-9.4/bin/postgresql94-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
 Main PID: 9243 (postgres)
   CGroup: /system.slice/postgresql-9.4.service
           tq9243 /usr/pgsql-9.4/bin/postgres -D /var/lib/pgsql/9.4/data
           tq9244 postgres: logger process
           tq9246 postgres: checkpointer process
           tq9247 postgres: writer process
           tq9248 postgres: wal writer process
           tq9249 postgres: autovacuum launcher process
           mq9250 postgres: stats collector process

 5月 29 07:21:00 test-centos7 systemd[1]: Starting PostgreSQL 9.4 database server...
 5月 29 07:21:00 test-centos7 pg_ctl[9239]: < 2015-05-29 07:21:00.929 JST >LOG:  ログ出力をログ収・セ・
 5月 29 07:21:00 test-centos7 pg_ctl[9239]: < 2015-05-29 07:21:00.929 JST >ヒント:  ここからのロ・..。
 5月 29 07:21:01 test-centos7 systemd[1]: Started PostgreSQL 9.4 database server.
Hint: Some lines were ellipsized, use -l to show in full.

無事、起動するようになった。
自動起動設定をする場合は、以下のコマンドを実行する。

systemctl enable postgresql-9.4
[root@test-centos7 ~]# systemctl enable postgresql-9.4
ln -s '/usr/lib/systemd/system/postgresql-9.4.service' '/etc/systemd/system/multi-user.target.wants/postgresql-9.4.service'

3.psqlコマンドを使ってみる

それでは、実際にpsqlコマンドを使ってPostgreSQLに接続してみよう。
postgresユーザに切り替えてpsqlコマンドを実行してみる。

su - postgres
psql
[root@test-centos7 ~]# su - postgres
最終ログイン: 2015/05/29 (金) 07:26:29 JST日時 pts/0
-bash-4.2$ psql
psql (9.4.2)
"help" でヘルプを表示します.

postgres=#

無事、PostgreSQLのコンソールにログインすることが出来るようになった。

内部構造から学ぶPostgreSQL 設計・運用計画の鉄則 (Software Design plus) 内部構造から学ぶPostgreSQL 設計・運用計画の鉄則 (Software Design plus)

PostgreSQLでデータベースごとの容量を確認する

$
0
0

仕事で、データベースのバックアップスクリプトの実行時間、負荷の関係からPostgreSQLでデータベースごとのファイル容量を調べる事があったので、念のため残しておく。
PostgreSQLでは、データベースごとの容量を調べる方法として幾つかの方法が用意されている。

1.「\l+」コマンドで確認する

一番カンタンな確認の仕方が、psqlで用意されている「\l+」コマンドの実行だろう。
通常、「\l」でデータベースの一覧が表示されるのだが、これに+を付け足すとデータベースサイズなどの情報も出力させることが出来る。

20150717_000020

2.SQLで情報を取得する

以下のようなSQLを実行することで、データベースの容量を取得することも出来る。

select t1.datname AS データベース名,
       pg_size_pretty(pg_database_size(t1.datname)) as データベースサイズ
from pg_database t1
order by pg_database_size(t1.datname) desc;

20150717_000021

 

内部構造から学ぶPostgreSQL 設計・運用計画の鉄則 (Software Design plus) 内部構造から学ぶPostgreSQL 設計・運用計画の鉄則 (Software Design plus)

MySQLでデータベースごとの容量を確認する

$
0
0

前回、PostgreSQLでのデータベースごとの容量確認方法について記述したので、今回はMySQLでの確認方法について。
MySQLでデータベースの容量を確認する場合は、以下のSQLを実行する。

SELECT table_schema "DB名",
Round(Sum(data_length + index_length) / 1024 / 1024, 1) "DBサイズ(MB)"
FROM information_schema.tables
GROUP BY table_schema;

20150718_000001

 

これで、データベースごとの容量を確認することが出来る。

 

たった2日でわかるSQL MySQL対応 たった2日でわかるSQL MySQL対応

MariaDBで構成されたGaleraClusterでテーブル暗号化を行う

$
0
0

先日、MariaDBでテーブルの暗号化を行ってみたが、今回はそれをGaleraClusterで行ってみる。
前回でも触れたが、この機能はMariaDB 10.1.3以降である必要がある。GaleraClusterの設定方法が10.0系と10.1系で少し違っているので、少し注意しよう。
10.1系でのGaleraClusterの設定については、こちらを参照してもらいたい。

今回はMariaDB 10.1.11、GaleraClusterはすでに構成済として進めていく。

1.鍵ファイルの作成・配布

さて、まずは前回と同じく鍵ファイルを作成、そのファイルを各ノードに配布する。
これについては、以後のメンテナンスを考慮して鍵ファイルをLsyncdで同期させるといいかも知れない。

openssl enc -aes-256-cbc -k パスワード -P -md sha1
[root@test-node ~]# openssl enc -aes-256-cbc -k Password1 -P -md sha1
salt=51C82DA044E0B1F1
key=F1FD7027872C000500DCF9D5FBBDFA624AF88551EA6D419C8922712FB85C97F7
iv =5D9E9DFEC73ACB0E1E4B17A1F058A7D2

上記コマンドの出力結果を元に、「key.txt」を以下の内容・記述で作成する。

暗号化・復号化する際の鍵番号;iv;key

上の例でいうと、以下のようにファイルを作成する。

[root@test-node ~]# cat /opt/key.txt
1;5D9E9DFEC73ACB0E1E4B17A1F058A7D2;F1FD7027872C000500DCF9D5FBBDFA624AF88551EA6D419C8922712FB85C97F7

「key.txt」を作成したら、さらにそれを暗号化した「key.enc」を以下のコマンドで作成する。

openssl enc -aes-256-cbc -md sha1 -k パスワード2 -in /opt/key.txt -out /opt/key.enc
[root@test-node ~]# openssl enc -aes-256-cbc -md sha1 -k Password2 -in /opt/key.txt -out /opt/key.enc
[root@test-node ~]# ls -la /opt/key.enc
-rw-r--r--. 1 root root 128  2月 12 10:55 /opt/key.enc
[root@test-node ~]# file /opt/key.enc
/opt/key.enc: data

 

鍵ファイルが作成出来たら、「/opt/key.enc」をscpなどで各ノードに配布する。

2.設定ファイルの追記

鍵ファイルの作成ができたら、次はMariaDBの設定ファイル「/etc/my.cnf.d/server.cnf」へ、暗号化について設定を追記する。

[mysqld]
plugin-load-add=file_key_management.so
file_key_management
file_key_management_filename = /PATH/key.enc
file_key_management_filekey = パスワード2
file_key_management_encryption_algorithm=AES_CBC

今回、実際に設定した値がこちら。

●MasterNode

[root@BS-PUB-GALERA-01 ~]# cat /etc/my.cnf.d/server.cnf
[mysqld]
bind-address=0.0.0.0
plugin-load-add=file_key_management.so
file_key_management
file_key_management_filename = /opt/key.enc
file_key_management_filekey = Password2
file_key_management_encryption_algorithm=AES_CBC

[galera]
wsrep_on=ON
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
binlog_format=ROW
wsrep_cluster_address='gcomm://'
wsrep_cluster_name='DBCLUSTER'
wsrep_node_name='DBCLUSTER-NODE1'
wsrep_node_address = IPアドレス

 

●OtherNode

[root@BS-PUB-GALERA-02 ~]# cat /etc/my.cnf.d/server.cnf
[mysqld]
bind-address=0.0.0.0
plugin-load-add=file_key_management.so
file_key_management
file_key_management_filename = /opt/key.enc
file_key_management_filekey = Password2
file_key_management_encryption_algorithm=AES_CBC

[galera]
wsrep_on=ON
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
binlog_format=ROW
wsrep_cluster_address = gcomm://MasterNodeIp,OtherNodeIp,...
wsrep_cluster_name='DBCLUSTER'
wsrep_node_name='DBCLUSTER-NODE2'
#wsrep_node_address = IPアドレス

 

後は、各ノードでMariaDBを起動させる。

service mysql start --wsrep-new-cluster # 1台目のノード(MasterNode)
service mysql start # 2台目以降のノード(OtherNode)

 

3.テーブル作成/設定変更

各ノードが起動したら、実際に暗号化したテーブルを作成してみよう。
どれか一つのノードで、以下のようにCREATE文を実行する。

CREATE TABLE TEST_ENCRIPTION(TEST_ID BIGINT NOT NULL PRIMARY KEY, TEST_VAR VARCHAR(80)) ENGINE=InnoDB &amp;nbsp;ENCRYPTED=YES ENCRYPTION_KEY_ID=1;
MariaDB [(none)]> use test
Database changed
MariaDB [test]> CREATE TABLE TEST_ENCRIPTION(TEST_ID BIGINT NOT NULL PRIMARY KEY, TEST_VAR VARCHAR(80)) ENGINE=InnoDB  ENCRYPTED=YES ENCRYPTION_KEY_ID=1;
Query OK, 0 rows affected (0.01 sec)

MariaDB [test]> INSERT INTO TEST_ENCRIPTION(TEST_VAR) VALUES("test");
Query OK, 1 row affected, 1 warning (0.00 sec)

MariaDB [test]> INSERT INTO TEST_ENCRIPTION(TEST_ID,TEST_VAR) VALUES(1,"test");
Query OK, 1 row affected (0.01 sec)

MariaDB [test]> SELECT * FROM TEST_ENCRIPTION;
+---------+----------+
| TEST_ID | TEST_VAR |
+---------+----------+
|       0 | test     |
|       1 | test     |
+---------+----------+
2 rows in set (0.00 sec)

 

正常に鍵ファイルが配置されていれば、他のノードでもテーブルへアクセス出来ることが確認できるだろう。
もちろん、鍵ファイルが無いノードでは中身が読めないので、ノードを追加する際は注意が必要。

[root@BS-PUB-GALERA-02 ~]# mysql -u root
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 4
Server version: 10.1.11-MariaDB MariaDB Server

Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> use test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [test]> SELECT * FROM TEST_ENCRIPTION;
ERROR 1296 (HY000): Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB

 

これで、もしDBのバックアップファイルを盗まれたとしても、鍵が無ければ中身を見れないので安心だ。
…普通にバックアップファイルを暗号化すればいいだけじゃないかと言われそうではあるけど。

エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド

MariaDB Serverのバージョンを確認する

$
0
0

MariaDB Serverのバージョンを確認する場合、何個か方法がある。

1.インストールされているパッケージからバージョンを確認する

rpmファイルやdpkgファイルからインストールされている場合(yumやapt-getも同様)、それらの情報からバージョンを確認する事が出来る。

●RHEL系の場合

rpm -qa | grep -i mariadb

 

●Debian/Ubuntuの場合

dpkg -l | grep -i mariadb

 

2.MariaDB Serverに接続して確認する

mysqlコマンドからMariaDBに接続してバージョンを確認することができる。
なお、特に説明は不要かと思うが、「mysql -V」で確認できるのは”mysqlクライアントの”バージョンなので注意が必要だ。

20160212_000000

[root@BS-PUB-GALERA-02 ~]# rpm -qa | grep -i mariadb
MariaDB-client-10.0.23-1.el7.centos.x86_64
MariaDB-common-10.0.23-1.el7.centos.x86_64
MariaDB-shared-10.0.23-1.el7.centos.x86_64
MariaDB-server-10.1.11-1.el7.centos.x86_64
[root@BS-PUB-GALERA-02 ~]#
[root@BS-PUB-GALERA-02 ~]# mysql -V
mysql  Ver 15.1 Distrib 10.0.23-MariaDB, for Linux (x86_64) using readline 5.1
[root@BS-PUB-GALERA-02 ~]# mysql --version
mysql  Ver 15.1 Distrib 10.0.23-MariaDB, for Linux (x86_64) using readline 5.1
[root@BS-PUB-GALERA-02 ~]#
[root@BS-PUB-GALERA-02 ~]# mysql -u root
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 7
Server version: 10.1.11-MariaDB MariaDB Server

Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

 

もしくは、MariaDBでstatusコマンドを実行することで、バージョン確認を行うと良いだろう。

[root@BS-PUB-GALERA-01 ~]# mysql -u root -e 'status'
--------------
mysql  Ver 15.1 Distrib 10.1.11-MariaDB, for Linux (x86_64) using readline 5.1

Connection id:          6
Current database:
Current user:           root@localhost
SSL:                    Not in use
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server:                 MariaDB
Server version:         10.1.11-MariaDB MariaDB Server
Protocol version:       10
Connection:             Localhost via UNIX socket
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    utf8
Conn.  characterset:    utf8
UNIX socket:            /var/lib/mysql/mysql.sock
Uptime:                 3 hours 39 min 35 sec

Threads: 3  Questions: 18  Slow queries: 0  Opens: 1  Flush tables: 3  Open tables: 1  Queries per second avg: 0.001
--------------

3.mysqladminから確認する

その他、mysqladminから確認する方法もある。

[root@BS-PUB-GALERA-01 ~]# mysqladmin -u root version
mysqladmin  Ver 9.1 Distrib 10.1.11-MariaDB, for Linux on x86_64
Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

Server version          10.1.11-MariaDB
Protocol version        10
Connection              Localhost via UNIX socket
UNIX socket             /var/lib/mysql/mysql.sock
Uptime:                 3 hours 41 min 13 sec

Threads: 3  Questions: 20  Slow queries: 0  Opens: 1  Flush tables: 3  Open tables: 1  Queries per second avg: 0.001

 

方法は何通りかあるので、環境に合わせて対応していこう。

 

Learning MySQL and MariaDB Learning MySQL and MariaDB

Corosync & PacemakerによるMaxscaleのHA化

$
0
0

Maxscaleのチュートリアルを読んでいたら、Corosync & Pacemakerを用いてのMaxscaleのHA化についてあったので、試してみる事にした。
今回利用するOSはCentOS 7を用い、Maxscaleはインストール済、SELinuxとFirewalldは無効化済とする。

なお、同じHAのカテゴリとしてLsyncdを用いる手法も紹介されていたが、正直これは単にmaxscale.confを自動同期させるだけでそこまで役に立つものでもないので無視する。

 

1.Corosync & Pacemakerのインストール

まずは、HA化に必要となるCorosync + Pacemakerをインストールする。

yum -y install pcs fence-agents-all

 

これで、パッケージのインストールが出来た。

 

2.クラスタ設定

さて、インストールが終わったら次はCorosync & Pacemakerの設定を行う。
まずは各ノードでホスト名での通信が行えるよう、hostsでIPアドレスとホスト名の紐付けを行う。

この際、自分自身には「current-node」という名称も付与する。
例えば、ホスト名が「BS-PUB-GFRONT-01」~「BS-PUB-GFRONT-03」まであったと仮定すると、hostsは以下のようになる。

●例:hosts(BS-PUB-GFRONT-01)

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
XXX.XXX.XXX.35 BS-PUB-GFRONT-01 current-node
XXX.XXX.XXX.36 BS-PUB-GFRONT-02
XXX.XXX.XXX.37 BS-PUB-GFRONT-03

 

●例:hosts(BS-PUB-GFRONT-03)

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
XXX.XXX.XXX.35 BS-PUB-GFRONT-01
XXX.XXX.XXX.36 BS-PUB-GFRONT-02
XXX.XXX.XXX.37 BS-PUB-GFRONT-03 current-node

 

hostsの設定が終わったら、各ノードでcorosyncで用いられるユーザ「hacluster」のパスワード設定を行う。

passwd hacluster

 

以下のコマンドを実行し、corosync及びpcsdを起動させる。

systemctl start corosync
systemctl start pcsd
systemctl enable pcsd

 

サービス起動後、以下のコマンドでcorosyncのノード認証を実施し、クラスタを作成・起動する。

pcs cluster auth ノード1 ノード2 ...&nbsp;-u hacluster -p パスワード --force # ノード認証
pcs cluster setup --name maxscale_cluster ノード1 ノード2 ... --force --transport udpu --mcastport0 5405 -- # クラスタ作成
pcs cluster start --all
[root@BS-PUB-GFRONT-01 ~]# pcs cluster auth BS-PUB-GFRONT-01 BS-PUB-GFRONT-02 BS-PUB-GFRONT-03 -u hacluster -p Password --force
BS-PUB-GFRONT-01: Authorized
BS-PUB-GFRONT-03: Authorized
BS-PUB-GFRONT-02: Authorized
[root@BS-PUB-GFRONT-01 ~]# pcs cluster setup --name maxscale_cluster BS-PUB-GFRONT-01 BS-PUB-GFRONT-02 BS-PUB-GFRONT-03 --force --transport udpu --mcastport0 5405
Shutting down pacemaker/corosync services...
Redirecting to /bin/systemctl stop  pacemaker.service
Redirecting to /bin/systemctl stop  corosync.service
Killing any remaining services...
Removing all cluster configuration files...
BS-PUB-GFRONT-01: Succeeded
BS-PUB-GFRONT-02: Succeeded
BS-PUB-GFRONT-03: Succeeded
Synchronizing pcsd certificates on nodes BS-PUB-GFRONT-01, BS-PUB-GFRONT-02, BS-PUB-GFRONT-03...
BS-PUB-GFRONT-01: Success
BS-PUB-GFRONT-03: Success
BS-PUB-GFRONT-02: Success

Restaring pcsd on the nodes in order to reload the certificates...
BS-PUB-GFRONT-01: Success
BS-PUB-GFRONT-03: Success
BS-PUB-GFRONT-02: Success
[root@BS-PUB-GFRONT-01 ~]# pcs cluster start --all
BS-PUB-GFRONT-03: Starting Cluster...
BS-PUB-GFRONT-02: Starting Cluster...
BS-PUB-GFRONT-01: Starting Cluster...

 

クラスタ起動後、しばらくしてから以下のコマンドを実行し、ステータス確認を行う。
(起動直後の場合、クラスタ間でのステータスが更新されておらず、Offlineになっていたりする)

pcs status
[root@BS-PUB-GFRONT-01 ~]# pcs status
Cluster name: maxscale_cluster
WARNING: no stonith devices and stonith-enabled is not false
Last updated: Tue Feb 16 07:13:17 2016          Last change: Tue Feb 16 07:10:34 2016 by root via cibadmin on BS-PUB-GFRONT-02
Stack: corosync
Current DC: BS-PUB-GFRONT-02 (version 1.1.13-10.el7-44eb2dd) - partition with quorum
3 nodes and 0 resources configured

Online: [ BS-PUB-GFRONT-01 BS-PUB-GFRONT-02 BS-PUB-GFRONT-03 ]

Full list of resources:


PCSD Status:
  BS-PUB-GFRONT-01: Online
  BS-PUB-GFRONT-02: Online
  BS-PUB-GFRONT-03: Online

Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled

 

クラスタが正常に構成されたことを確認したら、以下のコマンドを実行し設定を追加する。

crm configure property 'stonith-enabled'='false'
crm configure property 'no-quorum-policy'='ignore'
crm configure property 'placement-strategy'='balanced'
crm configure property 'cluster-infrastructure'='classic openais (with plugin)'
crm configure property 'expected-quorum-votes'='3'
[root@BS-PUB-GFRONT-01 ~]# crm configure property 'stonith-enabled'='false'
[root@BS-PUB-GFRONT-01 ~]# crm configure property 'no-quorum-policy'='ignore'
[root@BS-PUB-GFRONT-01 ~]# crm configure property 'placement-strategy'='balanced'
[root@BS-PUB-GFRONT-01 ~]# crm configure property 'cluster-infrastructure'='classic openais (with plugin)'
[root@BS-PUB-GFRONT-01 ~]# crm configure property 'expected-quorum-votes'='3'
[root@BS-PUB-GFRONT-01 ~]# crm configure show
node 1: BS-PUB-GFRONT-01
node 2: BS-PUB-GFRONT-02
node 3: BS-PUB-GFRONT-03
property cib-bootstrap-options: \
        have-watchdog=false \
        dc-version=1.1.13-10.el7-44eb2dd \
        cluster-infrastructure="classic openais (with plugin)" \
        cluster-name=maxscale_cluster \
        stonith-enabled=false \
        no-quorum-policy=ignore \
        placement-strategy=balanced \
        expected-quorum-votes=3

次に、以下のコマンドでmaxscaleのヘルスチェック関連の設定を追加する。

crm configure primitive MaxScale lsb:maxscale \
op monitor interval="10s" timeout="15s" \
op start interval="0" timeout="15s" \
op stop interval="0" timeout="30s"
[root@BS-PUB-GFRONT-01 ~]# crm configure primitive MaxScale lsb:maxscale \
> op monitor interval="10s" timeout="15s" \
> op start interval="0" timeout="15s" \
> op stop interval="0" timeout="30s"
[root@BS-PUB-GFRONT-01 ~]# crm configure show
node 1: BS-PUB-GFRONT-01
node 2: BS-PUB-GFRONT-02
node 3: BS-PUB-GFRONT-03
primitive MaxScale lsb:maxscale \
        op monitor interval=10s timeout=15s \
        op start interval=0 timeout=15s \
        op stop interval=0 timeout=30s
property cib-bootstrap-options: \
        have-watchdog=false \
        dc-version=1.1.13-10.el7-44eb2dd \
        cluster-infrastructure="classic openais (with plugin)" \
        cluster-name=maxscale_cluster \
        stonith-enabled=false \
        no-quorum-policy=ignore \
        placement-strategy=balanced \
        expected-quorum-votes=3

 

設定追加後、再度ステータスを確認する。

[root@BS-PUB-GFRONT-02 ~]# crm status
Last updated: Tue Feb 16 07:22:20 2016          Last change: Tue Feb 16 07:19:44 2016 by root via cibadmin on BS-PUB-GFRONT-01
Stack: classic openais (with plugin)
Current DC: BS-PUB-GFRONT-02 (version 1.1.13-10.el7-44eb2dd) - partition with quorum
3 nodes and 1 resource configured, 3 expected votes

Online: [ BS-PUB-GFRONT-01 BS-PUB-GFRONT-02 BS-PUB-GFRONT-03 ]

Full list of resources:

 MaxScale       (lsb:maxscale): Started BS-PUB-GFRONT-03

 

これで、クラスタの基本的な設定が完了した。

 

3.仮想IPの設定

次に、maxscaleクラスタで仮想IPを設定することで、共通のIPアドレスを指定しておけばノード障害が発生してもフェイルオーバーが発生するだけで済むようにする。
クラスタ構成ノードで、以下のコマンドを実行する。

crm configure primitive maxscale_vip ocf:heartbeat:IPaddr2 params ip=IPアドレス cidr_netmask=サブネット op monitor interval=10s
crm configure group maxscale_service maxscale_vip MaxScale

 

上記コマンド実行後、ステータスを確認すると以下のようになっている。

[root@BS-PUB-GFRONT-03 ~]# crm configure primitive maxscale_vip ocf:heartbeat:IPaddr2 params ip=172.28.0.230 cidr_netmask=24 op monitor interval=10s
[root@BS-PUB-GFRONT-03 ~]# crm configure group maxscale_service maxscale_vip MaxScale
[root@BS-PUB-GFRONT-03 ~]# crm status
Last updated: Tue Feb 16 08:29:12 2016          Last change: Tue Feb 16 08:29:10 2016 by root via cibadmin on BS-PUB-GFRONT-03
Stack: classic openais (with plugin)
Current DC: BS-PUB-GFRONT-02 (version 1.1.13-10.el7-44eb2dd) - partition with quorum
3 nodes and 2 resources configured, 3 expected votes

Online: [ BS-PUB-GFRONT-01 BS-PUB-GFRONT-02 BS-PUB-GFRONT-03 ]

Full list of resources:

 Resource Group: maxscale_service
     maxscale_vip       (ocf::heartbeat:IPaddr2):       Started BS-PUB-GFRONT-01
     MaxScale   (lsb:maxscale): Started BS-PUB-GFRONT-01

 

これで、クラスタで共通で利用される仮想IPの設定ができた。
なお、この仮想IPからmaxscaleに接続するにあたり、以下の設定を書き換える必要があるので注意。

[CLI Listener]
type=listener
service=CLI
protocol=maxscaled
#address=localhost
address=仮想IPアドレス
port=6603

 

これで、仮想IPアドレス(現時点だと、BS-PUB-GFRONT-01)から後ろのGaleraClusterに接続出来るようになった

[root@BS-PUB-GFRONT-02 ~]# mysql -u test -ppassword -h 172.28.0.230
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 20943
Server version: 5.5.42-MariaDB MariaDB Server

Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

 

なお、フェイルオーバーした際は自動的に元のマスターノードに戻らないので注意。
何かメンテナンスがある際は、ちゃんと直前にどこかマスターになっているのか確認すること。

[root@BS-PUB-GFRONT-02 ~]# crm status
Last updated: Tue Feb 16 08:46:51 2016          Last change: Tue Feb 16 08:46:24 2016 by hacluster via crmd on BS-PUB-GFRONT-03
Stack: corosync
Current DC: BS-PUB-GFRONT-03 (version 1.1.13-10.el7-44eb2dd) - partition with quorum
3 nodes and 2 resources configured

Online: [ BS-PUB-GFRONT-01 BS-PUB-GFRONT-02 BS-PUB-GFRONT-03 ]

Full list of resources:

 Resource Group: maxscale_service
     maxscale_vip       (ocf::heartbeat:IPaddr2):       Started BS-PUB-GFRONT-01
     MaxScale   (lsb:maxscale): Started BS-PUB-GFRONT-01

[root@BS-PUB-GFRONT-02 ~]# pcs cluster stop BS-PUB-GFRONT-01
BS-PUB-GFRONT-01: Stopping Cluster (pacemaker)...
BS-PUB-GFRONT-01: Stopping Cluster (corosync)...
[root@BS-PUB-GFRONT-02 ~]# crm status
Last updated: Tue Feb 16 08:47:02 2016          Last change: Tue Feb 16 08:46:24 2016 by hacluster via crmd on BS-PUB-GFRONT-03
Stack: corosync
Current DC: BS-PUB-GFRONT-03 (version 1.1.13-10.el7-44eb2dd) - partition with quorum
3 nodes and 2 resources configured

Online: [ BS-PUB-GFRONT-02 BS-PUB-GFRONT-03 ]
OFFLINE: [ BS-PUB-GFRONT-01 ]

Full list of resources:

 Resource Group: maxscale_service
     maxscale_vip       (ocf::heartbeat:IPaddr2):       Started BS-PUB-GFRONT-02
     MaxScale   (lsb:maxscale): Started BS-PUB-GFRONT-02

[root@BS-PUB-GFRONT-02 ~]# pcs cluster start BS-PUB-GFRONT-01
BS-PUB-GFRONT-01: Starting Cluster...
[root@BS-PUB-GFRONT-02 ~]# crm status
Last updated: Tue Feb 16 08:47:48 2016          Last change: Tue Feb 16 08:46:07 2016 by hacluster via crmd on BS-PUB-GFRONT-03
Stack: corosync
Current DC: BS-PUB-GFRONT-03 (version 1.1.13-10.el7-44eb2dd) - partition with quorum
3 nodes and 2 resources configured

Online: [ BS-PUB-GFRONT-01 BS-PUB-GFRONT-02 BS-PUB-GFRONT-03 ]

Full list of resources:

 Resource Group: maxscale_service
     maxscale_vip       (ocf::heartbeat:IPaddr2):       Started BS-PUB-GFRONT-02
     MaxScale   (lsb:maxscale): Started BS-PUB-GFRONT-02

 

これで、無事にMaxscaleの冗長化設定ができた。
動作としては、Active-Stanbyとなってしまうのだが、LB専用VMとしてMaxscaleを構築するのであれば、冗長化の一つの方法になるだろう。

 

エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド

Maxscaleで特定のノードを優先的にマスターとして取り扱うようにする

$
0
0

※この設定は、Maxscale 1.3.1以降で利用可能。それ以前では動作しなかったので注意。
MariaDBのLBとして利用出来るMaxscaleだが、Read/Write Spliterとして動作させた場合、通常はwsrep_local_indexの値がもっとも若い番号(基本的には0)がマスター(書き込みノード)として扱われる。

20160316_000000

 

で、このマスターに障害が発生した場合、Maxscale側でマスターを自動的に切り替えて書き込みを継続して出来るようにするのだが、Galera Clusterが復旧してwsrep_local_indexの値が変わると、自動的にMasterが切り替わってしまう。

20160316_000002

 

一応、マスター以外で障害が発生した場合には「disable_master_failback」というオプションを有効にすることでマスターノードが切り替わらないようにすることは出来るのだが、上のようにマスターノードに障害が発生した場合はあまり意味をなさない。Galera Clusterの原理を考えれば当たり前の話ではあるのだが、書き込みノードと読込みノードでは負荷の重さが違うので、可能であれば普段書き込みを行うノードだけスペックの高いノードを用いて、それ以外のノード(スレーブノード)のスペックを抑える事で費用等を抑えるような使い方をしたい。

そういった用途の場合は、「[Galera Monitor]」に「use_priority」を設定する事で、マスターノードの決め方をwsrep_local_indexの値から任意の順に変更出来るようだ。
以下、設定例。

●/etc/maxscale.conf(Before)

[maxscale]
threads=4 # 同時処理数
log_messages=1
log_trace=1
logdir=/var/log/maxscale

[Splitter Service]
type=service
router=readwritesplit
servers=BS-PUB-GALERA-01,BS-PUB-GALERA-02,BS-PUB-GALERA-03
max_slave_connections=100%
user=maxscale
passwd=パスワード
localhost_match_wildcard_host=true
enable_root_user=true

[Splitter Listener]
type=listener
service=Splitter Service
protocol=MySQLClient
port=3306

[Galera Monitor]
type=monitor
module=galeramon
servers=BS-PUB-GALERA-01,BS-PUB-GALERA-02,BS-PUB-GALERA-03
user=maxscale
passwd=パスワード
monitor_interval=3000

[CLI]
type=service
router=cli

[CLI Listener]
type=listener
service=CLI
protocol=maxscaled
address=127.0.0.1
port=6603

[BS-PUB-GALERA-01]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend

[BS-PUB-GALERA-02]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend

[BS-PUB-GALERA-03]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend

 

●/etc/maxscale.conf(After)

[maxscale]
threads=4 # 同時処理数
log_messages=1
log_trace=1
logdir=/var/log/maxscale

[Splitter Service]
type=service
router=readwritesplit
servers=BS-PUB-GALERA-01,BS-PUB-GALERA-02,BS-PUB-GALERA-03
max_slave_connections=100%
user=maxscale
passwd=パスワード
localhost_match_wildcard_host=true
enable_root_user=true

[Splitter Listener]
type=listener
service=Splitter Service
protocol=MySQLClient
port=3306

[Galera Monitor]
type=monitor
module=galeramon
servers=BS-PUB-GALERA-01,BS-PUB-GALERA-02,BS-PUB-GALERA-03
user=maxscale
passwd=パスワード
monitor_interval=3000
use_priority=true

[CLI]
type=service
router=cli

[CLI Listener]
type=listener
service=CLI
protocol=maxscaled
address=127.0.0.1
port=6603

[BS-PUB-GALERA-01]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=1

[BS-PUB-GALERA-02]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=2

[BS-PUB-GALERA-03]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=3

 

各ノードで設定している「priority」の値が小さいほど、優先的にマスターとして取り扱う。
今までMaxscaleを動作させていた環境であれば、念のためOS再起動をした方が良いだろう(自分の環境でそのまま利用してみたところ、ぱっと見は設定が終わっていたが、Queryログを見ると旧設定のまま接続を行っていたため)。
以下、実際の動作確認画面。

20160316_000006

 

念のため各ノードのQueryログをみてみたが、ちゃんと指定したマスターにINSERTやDELETEがいってる事は確認出来た。
これで、特定ノードだけを書き込み性能を引き上げて対応、といった事が可能になるだろう。

 

MariaDB&MySQL全機能バイブル MariaDB&MySQL全機能バイブル

MaxscaleでルーティングするSQLクエリの書き換えを行う

$
0
0

Maxscaleについて調べていたところ、中継するSQLクエリを正規表現で書き換えてDB側に伝える機能(Regex Filter)があるようだったので、少し触ってみる事にした。
※Maxscale 1.3.0以降で利用可能になったらしい。

書き換えルールについては、Maxscaleの設定ファイルに事前に書いておく必要があるので、以前書いたこちらの記事の設定を元にして記述していく。

●/etc/maxscale.cnf(Before)

[maxscale]
threads=4 # 同時処理数
log_messages=1
log_trace=1
logdir=/var/log/maxscale

[Splitter Service]
type=service
router=readwritesplit
servers=BS-PUB-GALERA-01,BS-PUB-GALERA-02,BS-PUB-GALERA-03
max_slave_connections=100%
user=maxscale
passwd=パスワード
localhost_match_wildcard_host=true
enable_root_user=true

[Splitter Listener]
type=listener
service=Splitter Service
protocol=MySQLClient
port=3306

[Galera Monitor]
type=monitor
module=galeramon
servers=BS-PUB-GALERA-01,BS-PUB-GALERA-02,BS-PUB-GALERA-03
user=maxscale
passwd=パスワード
monitor_interval=3000
use_priority=true

[CLI]
type=service
router=cli

[CLI Listener]
type=listener
service=CLI
protocol=maxscaled
address=127.0.0.1
port=6603

[BS-PUB-GALERA-01]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=1

[BS-PUB-GALERA-02]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=2

[BS-PUB-GALERA-03]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=3

●/etc/maxscale.cnf(After)

[maxscale]
threads=4 # 同時処理数
log_messages=1
log_trace=1
logdir=/var/log/maxscale

[regex]
type=filter
module=regexfilter
match=tset # "tset"という文字列があった場合
replace=test "test"という文字列に直す

[Splitter Service]
type=service
router=readwritesplit
servers=BS-PUB-GALERA-01,BS-PUB-GALERA-02,BS-PUB-GALERA-03
max_slave_connections=100%
user=maxscale
passwd=パスワード
localhost_match_wildcard_host=true
enable_root_user=true
filters=regex

[Splitter Listener]
type=listener
service=Splitter Service
protocol=MySQLClient
port=3306

[Galera Monitor]
type=monitor
module=galeramon
servers=BS-PUB-GALERA-01,BS-PUB-GALERA-02,BS-PUB-GALERA-03
user=maxscale
passwd=パスワード
monitor_interval=3000
use_priority=true

[CLI]
type=service
router=cli

[CLI Listener]
type=listener
service=CLI
protocol=maxscaled
address=127.0.0.1
port=6603

[BS-PUB-GALERA-01]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=1

[BS-PUB-GALERA-02]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=2

[BS-PUB-GALERA-03]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=3

 

とりあえず、この例では「tset」という文字列があった場合、「test」として置換してSQLを流すようにしている。
さて、それでは実際にSQLを流してみよう。

20160317_000000

[root@BS-PUB-GFRONT-01 ~]# mysql -u test test -ppassword -h 127.0.0.1 -e 'SELECT * FROM test'
+------+------+
| id   | name |
+------+------+
|    1 | test |
|    2 | test |
|    3 | test |
+------+------+
[root@BS-PUB-GFRONT-01 ~]# mysql -u test test -ppassword -h 127.0.0.1 -e 'SELECT * FROM tset'
ERROR 1146 (42S02) at line 1: Table 'test.tset' doesn't exist
[root@BS-PUB-GFRONT-01 ~]#
[root@BS-PUB-GFRONT-01 ~]# # ファイルを編集
[root@BS-PUB-GFRONT-01 ~]# vim /etc/maxscale.cnf
[root@BS-PUB-GFRONT-01 ~]# service maxscale restart
Restarting maxscale (via systemctl):                       [  OK  ]
[root@BS-PUB-GFRONT-01 ~]# mysql -u test test -ppassword -h 127.0.0.1 -e 'SELECT * FROM test'
+------+------+
| id   | name |
+------+------+
|    1 | test |
|    2 | test |
|    3 | test |
+------+------+
[root@BS-PUB-GFRONT-01 ~]# mysql -u test test -ppassword -h 127.0.0.1 -e 'SELECT * FROM tset'
+------+------+
| id   | name |
+------+------+
|    1 | test |
|    2 | test |
|    3 | test |
+------+------+
[root@BS-PUB-GFRONT-01 ~]# mysql -u test test -ppassword -h 127.0.0.1 -e 'INSERT INTO test(ID,NAME) VALUES(4,"tset");'
[root@BS-PUB-GFRONT-01 ~]# mysql -u test test -ppassword -h 127.0.0.1 -e 'SELECT * FROM tset'
+------+------+
| id   | name |
+------+------+
|    1 | test |
|    2 | test |
|    3 | test |
|    4 | test |
+------+------+

 

ううむ、確かにSQLが置換されている事がわかる。
ある程度オーバーヘッドがありそうな気もするけど、そこまで大きくはなさそうだ。

オプションを見ていると、特定のホストやユーザーの場合だけ置換をさせるように指定することも出来そうなので、使いドコロによっては面白そうだ。

 

サーバ負荷分散入門 サーバ負荷分散入門

MaxscaleでSQLクエリの内容に応じてルーティング先のDBサーバを指定する

$
0
0

Maxscaleについて調べていたところ、中継するSQL文の内容に応じて、指定したサーバにSQLを飛ばすように出来るフィルター機能(Named Server Filter)があるようなので、試してみる事にした。
なお、検証に用いたMaxscaleのバージョンは1.3.1を利用している。

今回は、SQL文に「five」という文字列があった場合は特定のサーバに行く、というような記述をしてみる。

●/etc/maxscale.cnf(Before)

[maxscale]
threads=4 # 同時処理数
log_messages=1
log_trace=1
logdir=/var/log/maxscale

[Splitter Service]
type=service
router=readwritesplit
servers=BS-PUB-GALERA-01,BS-PUB-GALERA-02,BS-PUB-GALERA-03
max_slave_connections=100%
user=maxscale
passwd=パスワード
localhost_match_wildcard_host=true
enable_root_user=true

[Splitter Listener]
type=listener
service=Splitter Service
protocol=MySQLClient
port=3306

[Galera Monitor]
type=monitor
module=galeramon
servers=BS-PUB-GALERA-01,BS-PUB-GALERA-02,BS-PUB-GALERA-03
user=maxscale
passwd=パスワード
monitor_interval=3000
use_priority=true

[CLI]
type=service
router=cli

[CLI Listener]
type=listener
service=CLI
protocol=maxscaled
address=127.0.0.1
port=6603

[BS-PUB-GALERA-01]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=1

[BS-PUB-GALERA-02]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=2

[BS-PUB-GALERA-03]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=3

●/etc/maxscale.cnf(After)

threads=4 # 同時処理数
log_messages=1
log_trace=1
logdir=/var/log/maxscale

[NamedServerFilter]
type=filter
module=namedserverfilter
match=five
options=ignorecase
server=BS-PUB-GALERA-02

[Splitter Service]
type=service
router=readwritesplit
servers=BS-PUB-GALERA-01,BS-PUB-GALERA-02,BS-PUB-GALERA-03
max_slave_connections=100%
user=maxscale
passwd=パスワード
localhost_match_wildcard_host=true
enable_root_user=true
filters=NamedServerFilter

[Splitter Listener]
type=listener
service=Splitter Service
protocol=MySQLClient
port=3306

[Galera Monitor]
type=monitor
module=galeramon
servers=BS-PUB-GALERA-01,BS-PUB-GALERA-02,BS-PUB-GALERA-03
user=maxscale
passwd=パスワード
monitor_interval=3000
use_priority=true

[CLI]
type=service
router=cli

[CLI Listener]
type=listener
service=CLI
protocol=maxscaled
address=127.0.0.1
port=6603

[BS-PUB-GALERA-01]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=1

[BS-PUB-GALERA-02]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=2

[BS-PUB-GALERA-03]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=3

 

このように設定することで、文字列「five」が含まれているSQLが指定したサーバに向くことをクエリーログから確認できた。
なお、一応上下関係があるようで、Read/Write Splitの方が優先されるのか、INSERT文はそのままマスターノードに行った。

 

サーバ負荷分散入門 サーバ負荷分散入門

MaxscaleのLimitations and Knownを読んでみた

$
0
0

仕事でMaxscaleを利用しているのだが、Limitation and Knownを読んでなかったので読むことにした。
そんなに文章量も無いので、以下重要そうなトコだけ抜粋して記述していく。

MySQL Serverのハンドシェイクに圧縮は含まれない

Compression is not included in MySQL server handshake

 

Galera Cluster Monitorではデフォルトのマスターは「wsrep_local_index」が最も低いノードが対象となる

The default master selection is based only on MIN(wsrep_local_index). This
can be influenced with the server priority mechanic described in the
Galera Monitor manual.

これはMaxscale+ Galera Clusterの組み合わせでいじってるとスグ気がつく部分だと思う。
マスターを優先順位を付けて指定したい場合は、こちらの内容を元に対応すると良いだろう。

 

Connection Router では接続中のマスターの変化を認識出来ない

If Master changes (ie. new Master promotion) during current connection the router cannot check the change.

つまり、Read Write Splittingじゃないと、マスターの切り替えには対応出来ないということなのだろうか。

 

Connection Router ではLONGBLOBデータの送信はサポートされない

Sending of LONGBLOB data is not supported

 

Read Write Splittingでは、特定条件のSQLは全てマスターノードに振り分けられる

Read queries are routed to the master server in the following situations:

  • if they are executed inside an open transaction
  • in case of prepared statement execution
  • statement includes a stored procedure, or an UDF call
  • if there are multiple statements inside one query e.g.
    INSERT INTO ... ; SELECT LAST_INSERT_ID();

これについては、Galera Cluster + Maxscaleを利用している人は要注意だ。
自分も会社で利用していた際に引っかかった所なのだけど、以下の場合だとSQLの内容がSELECTだろうがINSERTだろうが全てマスターノードに寄ってしまうので、処理が分散されない事になる。

  • オープントランザクションで処理を実行する場合
  • Prepared Statement(プリペアドステートメント)を利用する場合
  • ストアド・プロシージャで値の代入やUDFを呼び出している場合
  • 一つのクエリの中で複数のSQL文がある場合(;で区切っていくつもSQL文を実行している場合)

Go言語でいうと、例えばGenmaiとか使ってると、全てのSQLがマスターノードで処理されてしまうということになる。
マルチマスタなのに負荷分散されないという、なかなか意味のないクラスタとなるので注意が必要。

一つのクエリ内で複数のSQLを処理している場合

When a multi-statement query is executed through the readwritesplit router, it will always be routed to the master. With the default configuration, all queries after a multi-statement query will be routed to the master to prevent possible reads of false data.

You can override this behavior with the strict_multi_stmt=false router option. In this mode, the multi-statement queries will still be routed to the master but individual statements are routed normally. If you use multi-statements and you know they don’t modify the session state in any relevant way, you can disable this option for better performance.

For more information, read the ReadWriteSplit router documentation.

一つのクエリ内で複数のSQLを処理している場合、その処理がreadwritesplitrouterを経由している場合、全てマスターノードに振り分けられる事になる。
これを解消するには、readwritesplitrouterの設定にオプションとして「strict_multi_stmt=false」を設定する必要があるようだ。この設定を追加することで、複数処理を記述したSQLはマスターにも割り振られるものの、スレーブノード側にもちゃんと割り振ってくれるようになるらしい。

 

クライアントセッションの処理における制限

Some of the queries that client sends are routed to all backends instead of sending them just to one of server.
These queries include USE <db name> and SET autocommit=0 among many others. Readwritesplit sends a copy of these queries to each backend server and forwards the master’s reply to the client.

一部のクエリ(USE <DB名>など)については、1サーバではなくバックグラウンドの全てのサーバにルーティングされるようだ。

 

Server-side session variables are called as SQL variables. If “master” is set, SQL variables are read and written in master only. Autocommit values and prepared statements are routed to all nodes always.

サーバ側のセッション変数はSQL変数として読み込まれ、もしバックグラウンド側にマスターがいるようであれば、SQL変数はマスターでのみ読み書きされる(マスターだけで処理される)。オートコミット値及びプリペアステートメントについては、全てのノードにルーティングされる。

つまり、プリペアドステートメントを使っている場合、クエリ自体は全てのノードに送られるが、実際の処理はマスターでのみ行われる(処理が偏る)ということになる。

 

If a SELECT query modifies a user variable when the se_sql_variables_in parameter is set to all, it will not be routed and the client will receive an error.
A log message is written into the log further explaining the reason for the error.

「use_sql_variables_in = all」が設定されている場合、SELECTクエリがユーザー変数を変更した場合、ルーティングされずエラーが返ってくるとのこと。
これを解消するには、「use_sql_variables_in = master」を設定するとのこと。

 

Maxscaleの認証関係の制限

  • MaxScale can not manage authentication that uses wildcard matching in hostnames in the mysql.user table of the backend database. The only wildcards that can be used are in IP address entries.
  • MySQL old style passwords are not supported. MySQL versions 4.1 and newer use a new authentication protocol which does not support pre-4.1 style passwords.
  • When users have different passwords based on the host from which they connect MaxScale is unable to determine which password it should use to connect to the backend database. This results in failed connections and unusable usernames in MaxScale.
  • MaxScaleでは、MySQLでホスト名にワイルドカードマッチングを使用して認証を管理することはできない。
    (IPアドレスでのワイルドカードは利用可能)
  • MySQLバージョン4.1以前のパスワードは対応していない。
  • 接続しにいくノードのユーザ名とパスワードは、全て同一である必要がある(ノードごとに異なるパスワードは設定出来ない)。

 

Schemarouterの制限について

The schemarouter router currently has some limitations due to the nature of the sharding implementation and the way the session variables are detected and routed. Here is a list of the current limitations.

  • Cross-database queries (e.g. SELECT column FROM database1.table UNION select column FROM database2.table) are not supported and are routed either to the first explicit database in the query, the current database in use or to the first available database, if none of the previous conditions are met.
  • Without a default database, queries without explicit databases that do not modify the session state will be routed the first available server. This means that, for example when creating a new database, queries should be done directly on the node or the router should be equipped with the hint filter and a routing hint should be used. Queries that modify the session state e.g. SET autocommit=1 will be routed to all servers regardless of the default database.
  • SELECT queries that modify session variables are not currently supported because uniform results can not be guaranteed. If such a query is executed, the behavior of the router is undefined. To work around this limitation the query must be executed in separate parts.
  • If a query targets a database the schemarouter hasn’t mapped to a server the query will be routed to the first available server. This possibly returns an error about database rights instead of a missing database.

Schemarouterでは、以下のような制限があるらしい。

  • クロスデータベースクエリはサポートしていない。
    2つ目以降のデータベース指定は全て最初に指定したデータベースにルーティングされる。
  • デフォルトデータベースがないと、明示的なデータベース指定の無い、セッション状態を変更しないクエリは、最初に使用可能なサーバへルーティングされる。
  • 均一な結果を保証できないため、セッション変数を変更するようなSELECTクエリは現在サポートされていない。
  • schemarouterは、クエリがデータベースをターゲットにしている場合はクエリが最初に使用可能なサーバーにマッピングされていません。

 

大体合ってるだろうか。
基本、Maxscaleを利用している場合の大半はReadWriteSplittingを用いる事が多いだろうと思う(個人的な感想)ので、その辺りの制限についてはちゃんと読んでおいた方が良さそうだ。

 

おうちで学べるデータベースのきほん おうちで学べるデータベースのきほん

Maxscale のRead Write Splittingでマスターも読み込みに利用する

$
0
0

MaxscaleのRead Write Splittingでは、通常ではマスターは書き込みのみが割り当てられ、通常のSELECT文は割り振られないようになっている。
これを、マスターにもSELECT文を割り当てたい場合は、以下の設定値を「/etc/maxscale.cnf」に追記する。

master_accept_reads=true

これで、SELECT文もマスターに割り当てられるようになるだろう。

【参考】

https://mariadb.com/kb/en/mariadb-enterprise/mariadb-maxscale/readwritesplit/

 

Learning MySQL and MariaDB Learning MySQL and MariaDB

SQLite3でテーブル一覧を取得する

$
0
0

sqlite3でテーブルの一覧を取得する場合、以下のようにコマンドを実行する。

.tables

もしくは

select name from sqlite_master where type='table';

で一覧が取得出来る。

sqlite> .table
TEST
sqlite> select name from sqlite_master where type='table';
TEST

 

テーブルのCREATE文を見る場合は、以下のようにコマンドを実行する。

.schema テーブル名
sqlite> .schema TEST
CREATE TABLE TEST (
  ID nchar(6),
  NAME int,
  Date datetime
);

 

Using SQLite Using SQLite

phpでSQLで取得した複数行・複数列の内容をそのまま出力させる(多次元連想配列)

$
0
0

仕事で何故かPHPを少し触る事になった。
で、その中でPHPで作られたコマンドラインツールでクエリの結果(複数行・複数列)をそのまま出力させたい箇所があり、以下のように多次元連想配列を利用すると簡単に書けたので備忘として残しておく。
※以下の例では、PDOを使用してSQLiteに接続している。

●test.php

/*
 ==== 変数 ====
*/
$dbfile  = 'test.db'; // 使用するDBファイル
$dbtable = 'TEST';    // SQLを実行するテーブル名
$dbwhere = 'AAA';     // SQLで検索する文字列
$dbcolum = 3;         // 取得するカラム数(列数)

/*
 ==== 関数 ====
*/
// DB接続処理
function SQLite_Connect($sqlite_dbfile)
{
    $dsn = 'sqlite:'. $sqlite_dbfile;
    return new PDO($dsn);
    $opt = array(
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
    );
    return new PDO($dsn,'','', $opt);
}

/*
 ==== Main ====
*/
// DB接続
$pdo=SQLite_Connect($dbfile);

// 実行するクエリの定義
$query = "SELECT  `ID`
                 ,`NAME`
                 ,`DATE`
          FROM   `". $dbtable ."`
          WHERE  `NAME` LIKE '%" . $dbwhere ."%';";

// SQLの実行
$stmt = $pdo->query($query);

// SQLの実行結果を多次元連想配列で処理する
$result = $stmt->fetchAll();
foreach ($result as $key=>$val) {
    $k=0;
    while ($k <= ( $dbcolum - 1)) {
        print $val[$k] ;
        $k=$k+1;
        if ($k < $dbcolum){
            print ",";
        }
    }
    print "\n";
}

20160417_000005

[root@localhost ~]# sqlite3 ./test.db --batch 'SELECT * FROM TEST WHERE NAME LIKE "AAA"; '
1|AAA|2016-04-17 04:01:16
2|AAA|2016-04-17 04:01:17
12|AAA|2016-04-17 04:02:05
13|AAA|2016-04-17 04:02:06
14|AAA|2016-04-17 04:02:06
[root@localhost ~]# php test.php
1,AAA,2016-04-17 04:01:16
2,AAA,2016-04-17 04:01:17
12,AAA,2016-04-17 04:02:05
13,AAA,2016-04-17 04:02:06
14,AAA,2016-04-17 04:02:06

 

独習PHP 第3版 独習PHP 第3版

Maxscaleで「Too many open files. Failed to accept new client connection.」エラーが出た際の対応

$
0
0

会社のシステム(Maxscale経由でDBに接続)で負荷テストをしていたところ、不可解な接続エラーが発生していた。どうも新しいセッションが作成出来ないとの事なのだが、後ろのMariaDB側のMax Connection値は余裕がある。で、いろいろと調べていたところ、Maxscaleのエラーログに以下のようなエラーが出ていた。

2016-04-26 16:53:56   Error 24, Too many open files. Failed to accept new client connection.

 

Oh…(´・ω・`)

どうやら、ファイルディスクリプタが上限を超えてしまったらしい。デフォルトの値(1024)では足らぬようだ。
※現在のファイルディスクリプタ数は以下のコマンドで確認できる。

cat /proc/$(pgrep maxscale)/limits
[root@BS-PUB-GFRONT-01 ~]# cat /proc/$(pgrep maxscale)/limits | awk '{if(NR==1 || /Max open files/) print}'
Limit                     Soft Limit           Hard Limit           Units
Max open files            1024                 4096                 files

 

とにかく、足らないなら上限を引き上げるしかない。
Maxscaleのファイルディスクリプタを引き上げるには、「/usr/lib/systemd/system/maxscale.service」で、「[Service]」以下に「LimitNOFILE=65536」を追記してやり、サービスを再起動してやれば良い(CentOS 7の場合)。

●/usr/lib/systemd/system/maxscale.service

…
[Service]
…
LimitNOFILE=65536
…

追記したら、以下のコマンドでMaxscaleを再起動する。

systemctl daemon-reload
systemctl restart maxscale

 

これで、ファイルディスクリプタの上限が変更できた。

[root@BS-PUB-GFRONT-01 ~]# cat /proc/$(pgrep maxscale)/limits | awk '{if(NR==1 || /Max open files/) print}'
Limit                     Soft Limit           Hard Limit           Units
Max open files            65536                65536                files

 

理論から学ぶデータベース実践入門 ~リレーショナルモデルによる効率的なSQL (WEB+DB PRESS plus) 理論から学ぶデータベース実践入門 ~リレーショナルモデルによる効率的なSQL (WEB+DB PRESS plus)

CentOS 7にRethinkDBをインストールしてみる

$
0
0

先日、仕事で負荷テストを行っていた際、RethinkDBなるNoSQL(JSONデータベース)があることを知ったので、試しに入れてみる事にした。
MongoDBに比べるとパフォーマンス面では劣る面があるようだけど、テーブルのjoinをしたりといったRDBMSっぽいこともできるようだ。こちらを見ると、MongoDBが書き込み時(読み込み時もか?)にDBロックを書けることが多いのに対し、ロック無しでトランザクションを実現する事が可能らしい。
(まぁ、今回はあくまでもお試しなので、CentOS 7に入れて少しいじってみるだけなのだが)

1.インストール

まずはインストール。
こちらを参考に、yumから入れるだけだ。

sudo wget http://download.rethinkdb.com/centos/7/`uname -m`/rethinkdb.repo -O /etc/yum.repos.d/rethinkdb.repo
sudo yum install rethinkdb

 

インストールが完了したら、systemd経由で起動するように以下のコマンドを実行する。

echo "d /run/rethinkdb 0755 rethinkdb rethinkdb -" > /usr/lib/tmpfiles.d/rethinkdb.conf
cat <<EOF > /usr/lib/systemd/system/rethinkdb@.service
[Unit]
Description=RethinkDB database server for instance '%i'

[Service]
User=rethinkdb
Group=rethinkdb
ExecStart=/usr/bin/rethinkdb serve --config-file /etc/rethinkdb/instances.d/%i.conf
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF
chmod 644 /usr/lib/systemd/system/rethinkdb@.service
rethinkdb create -d /opt/rethinkdb
chown -R rethinkdb.rethinkdb /opt/rethinkdb
cp /etc/rethinkdb/default.conf.sample /etc/rethinkdb/instances.d/instance1.conf
sed -e '/# directory/c directory=/opt/rethinkdb' \
    -e '/# bind/c bind IPアドレス' \
    -i /etc/rethinkdb/instances.d/instance1.conf

 

後は、サービスを起動するだけだ。

systemctl enable rethinkdb@instance1
systemctl start rethinkdb@instance1

 

これでRethinkDBが利用できるようになった。

 

2.Webコンソールへ接続してみる

さて、それでは実際にRethinkDBに接続してみよう。
RethinkDBではWebコンソール(http://IPアドレス:8080)が用意されているようなので、まずはそちらにアクセスする。
認証は特に無いようだ。

Screenshot_from_2016-05-06 17:34:08

 

「Table」から、データベースとテーブルを作成してみる。

Screenshot_from_2016-05-06 17:40:06

Screenshot_from_2016-05-06 17:40:23

Screenshot_from_2016-05-06 17:40:29

Screenshot_from_2016-05-06 17:40:36

Screenshot_from_2016-05-06 17:40:46

 

「Data Explorer」から、ReQL(RethinkDB操作用の言語)を用いてデータを操作することが出来る。
置換もできるようだし、書き方は結構簡単だと思う。

r.db('DB名').table('テーブル名').filter({キー名: 値,...}) # SELECT
r.db('DB名').table('テーブル名').insert({キー名: 値,...}) # INSERT
r.db('DB名').table('テーブル名').filter({キー名: 値,...}).delete() # DELETE

Screenshot_from_2016-05-06 18:13:53

Screenshot_from_2016-05-06 18:22:55

Screenshot_from_2016-05-06 18:29:19

 

3.Pythonからアクセスする

残念ながら、クライアント用のコマンドというものは用意されていないようなので、Pythonなどで書いてあげる必要がある。
まず、以下のコマンドでRethinkDBへアクセスするためのライブラリを導入する。

pip install rethinkdb

 

後は、Pythonで記述してやるだけだ。

python
import rethinkdb as r
r.connect('localhost', 28015).repl()
r.db('testdb').table('testtb').insert({'id': 1,'title': 'test1','contents': 'test'}).run()
r.db('testdb').table('testtb').insert({'id': 2,'title': 'test2','contents': 'test'}).run()
r.db('testdb').table('testtb').insert({'id': 3,'title': 'test3','contents': 'test'}).run()
r.db('testdb').table('testtb').filter({'id': 1}).run()
r.db('testdb').table('testtb').get(2).run()
[root@BS-PUB-CENT7-01 ~]# python
Python 2.7.5 (default, Nov 20 2015, 02:00:19)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import rethinkdb as r
>>> r.connect('localhost', 28015).repl()

>>> r.db('testdb').table('testtb').insert({'id': 1,'title': 'test1','contents': 'test'}).run()
{u'skipped': 0, u'deleted': 0, u'unchanged': 0, u'errors': 0, u'replaced': 0, u'inserted': 1}
>>> r.db('testdb').table('testtb').insert({'id': 2,'title': 'test2','contents': 'test'}).run()
{u'skipped': 0, u'deleted': 0, u'unchanged': 0, u'errors': 0, u'replaced': 0, u'inserted': 1}
>>> r.db('testdb').table('testtb').insert({'id': 3,'title': 'test3','contents': 'test'}).run()
{u'skipped': 0, u'deleted': 0, u'unchanged': 0, u'errors': 0, u'replaced': 0, u'inserted': 1}
>>> r.db('testdb').table('testtb').filter({'id': 1}).run()

>>> r.db('testdb').table('testtb').get(2).run()
{u'id': 2, u'contents': u'test', u'title': u'test2'}

 

クラスタ組めるようだし、まぁ悪くないような…

RDB技術者のためのNoSQLガイド RDB技術者のためのNoSQLガイド

CentOS 7にCockroachDBをインストールしてみる

$
0
0

以前、仕事中の負荷テスト時の調べ物でCockroachDBなるものを知ったので、試しにCentOS 7に入れてみることにする。
CockroachDBはいわゆるNewSQLと呼ばれるDBで、NoSQLでトランザクションをできるようにしたものだと覚えておけばよいだろう。特にこのCockroachDBは分散KeyValueStoreで、データを分散して保存させることに力を入れているらしい。データベース内の操作はSQLで行えるので、RDBMSからの移行も比較的簡単に行えるだろう。

現時点(2016/05時点)ではまだBeta版のようなので本番導入はちょっとどうかと思うが、面白い代物だと思う。
なお、ロゴ見てもらえりゃわかると思うけど、Cockroachってまぁゴキさんです。
火星にいるあいつです(違う)。

1.インストール

インストール方法については、ソースからやバイナリをそのまま、もしくはDockerでの動作を選択できるようだ。
とりあえず、今回はバイナリからインストールを行う。

以下のコマンドで、最新版のバイナリをダウンロードする。

curl -s https://www.cockroachlabs.com/docs/install-cockroachdb.html | grep 'CockroachDB tarball for Linux' | awk -F\" '{print $2}' | xargs wget

 

バイナリのアーカイブファイルをダウンロードしたら、以下のコマンドで展開、実行ファイルをコピーする。

tar xzvf cockroach-beta-*.tgz
cp cockroach-beta-20160505.linux-amd64/cockroach /usr/bin/

 

これでインストールは完了となる。

2.起動・接続

さて、それでは実際に起動・接続してみよう。
まず、以下のコマンドでバックグラウンド実行する。

cockroach start --background
[root@BS-PUB-CENT7-02 ~]# cockroach start --background
build:     beta-20160505 @ 2016/05/05 15:41:00 (go1.6)
admin:     http://localhost:8080
sql:       postgresql://root@localhost:26257?sslmode=disable
logs:      cockroach-data/logs
store[0]:  path=cockroach-data

 

インスタンスを複数立ち上げる場合は、2つ目以降は以下のようにコマンドを実行してやれば良いようだ。

cockroach start --store=データストア名 --port=ポート番号(DB) --http-port=ポート番号(http) --join=localhost:26257 --background

 

さて、これでCockroachDBは起動出来たので、接続してデータベース・テーブルを作成してみよう。
CockroachDBのクライアントは、同じバイナリでサブコマンドとして「sql」を付与すれば良い。

cockroach sql
[root@BS-PUB-CENT7-02 ~]# cockroach sql
# Welcome to the cockroach SQL interface.
# All statements must be terminated by a semicolon.
# To exit: CTRL + D.
root@:26257> CREATE DATABASE test;
CREATE DATABASE
root@:26257> SET DATABASE = test;
SET
root@:26257> CREATE TABLE test (id INT PRIMARY KEY, value DECIMAL);
CREATE TABLE
root@:26257> INSERT INTO test VALUES (1111, DECIMAL '912.234');
INSERT 1
root@:26257> INSERT INTO test VALUES (1112, DECIMAL '9432.134');
INSERT 1
root@:26257> SELECT * FROM test;
+------+----------+
|  id  |  value   |
+------+----------+
| 1111 |  912.234 |
| 1112 | 9432.134 |
+------+----------+

 

ふむぅ…特に違和感なく操作出来る。
ただまぁ、分散方式に力が入っているとのことなので、クラスタにしてみないとなんとも判断出来ないかな。

 

RDB技術者のためのNoSQLガイド RDB技術者のためのNoSQLガイド
Viewing all 33 articles
Browse latest View live