CentOS から Windows上のSQLServerへの道のり

副題: Road to SQLServer on Windows. (^^;

【追記 2019年3月12日】
CentOS7 と PHP7系については、こちらにまとめてます。
https://ptsv.jp/repository/rhel7-php71-sqlserver/


備忘録です。

今まで、CentOS6からSQLServerへのアクセスは、FreeTDS を使っていました。PHPからはPDO_DBLIB 経由。これは結構簡単にセットアップできました。yum で FreeTDSとか、もっと簡単に、php-sybaseなりphp-mssqlなり入れれば依存関係で必要なライブラリは勝手にインストールされますしね。設定自体も、/etc/freetds.conf と /etc/locales.conf とかいじればあとは、PDOからアクセスできます。

で、非常に疎かったので知らなかったんですが、Microsoftから Linux向けのSQLServer ODBCドライバが供給されている、とのこと。

今更何言ってんの??? って感じですが、知らなかったものはしょうがない。説明通りにやってみます(^^;

# curl https://packages.microsoft.com/config/rhel/6/prod.repo > /etc/yum.repos.d/mssql-release.repo
exit root

$ sudo ACCEPT_EULA=Y yum install msodbcsql
$ sudo ACCEPT_EULA=Y yum install mssql-tools
$ sudo yum install unixODBC-devel
$ sudo ln -sfn /opt/mssql-tools/bin/sqlcmd /usr/bin/sqlcmd
$ sudo ln -sfn /opt/mssql-tools/bin/bcp /usr/bin/bcp

エラーもなく、インストール完了。
ここまでは説明書通り。

さて、ここから設定。

/etc/odbcinst.ini を開くと、以下のセクションが追加されているはず。

[ODBC Driver 13 for SQL Server]
Description=Microsoft ODBC Driver 13 for SQL Server
Driver=/opt/microsoft/msodbcsql/lib64/libmsodbcsql-13.1.so.6.0
UsageCount=1

そして、/etc/odbc.ini を編集します。僕の環境ではodbc.ini は空のファイルでした。
データソースを記述していきます。

[Development]
Driver = ODBC Driver 13 for SQL Server #odbcinst.ini に追加されたセクション名
Description = for development databse #適当
Trace = Yes #わからん。 
Server = 10.1.1.1 #稼働中のSQLServerのIPアドレスもしくはホスト名 ファイヤーウォールでアクセス許可を出すこと。
Port = 1433 #SQLServer Configuration Manager で TCP/IP を有効に。
Database = Sample  #データベース名

この状態で、まず、isql コマンドで接続してみます。書式は、isql [データソース名] [ユーザー名] [パスワード]ですね。

$ isql Development dbuser dbpass
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> select count(*) from hogehoge
+------------+
|            |
+------------+
| 5500       |
+------------+
SQLRowCount returns 0
1 rows fetched
SQL>

無事接続できました!

今度は、マイクロソフトが提供しているツールを使用してみましょう。

$ sqlcmd -S 10.1.1.1  -U dbuser
Password: xxxxxx
1> use Sample
2> go
データベース コンテキストが 'Sample' に変更されました。
1> select count(*) from hogehoge
2> go

-----------
       5500

(1 rows affected)
1>

接続できました。

次に、PHP で PDO_ODBC経由で接続してみます。
DSNには、odbc.ini で設定した、データソース名ではなく、ドライバ名・サーバー名・データベース名をそれぞれ直接指定してみました。

$ php -a
Interactive shell

php > $pdo = new PDO('odbc:Driver={ODBC Driver 13 for SQL Server};Server=10.1.1.1;Database=Sample','dbuser','dbpass');
php > $sth = $pdo->query('select count(*) from hogehoge');
php > echo $sth->fetchColumn();
5500
php >

接続できました。

日本語(UTF-8)が正常にCRUDできるか、まだテストしていませんが、とりあえずは、正常に接続できることを確認できたことでヨシとしましょう。

:continue 続きはこちら

やっぱりWSLでCentOSが使いたい(挫折編)

#2018年9月1日追記
この記事はベータ版時代のWSLに関するものですので、ご注意ください。具体的には LxRun コマンドでインストールされるLegacy版が対象です。
主なディストリビューションに関してはストア版を導入した方が管理も楽でしょうし、debian系、slackware系もそろってますし、redhat系のディストリビューションもそのうちリリースされることでしょう・・・いやしてほしい。以前 fedora もマイクロソフトストア配布されてた思うんですが・・・消えてますね・・・。

また、WSL-DistroLauncher というWSL用ディストリビューションのインストーラー・起動アプリのリファレンス実装サンプルをマイクロソフトが公開していますので、そちらで好みのディストリビューションをWSL用にパッケージングが試せます。また勉強がてらに試してみよう。。。
※ツールのビルドにVisual Studio 2017 community が必要です。

#2018年5月19日追記
コマンドラインの記述が一部間違っておりました。
インストールしたディストリビューションの切替の箇所でswitch.pyと記述しないといけないところを、install.py と間違えていました。記事内修正しました。
また、Windows10 の Spring Creators Update を適用してから CentOS をインストールして切り替えて使ってみた感じ、特にエラーもなく使えるようになってまつね・・・。いいぞ、Microsoft! この調子で、マイクロソフト製の ちゃんと使えるターミナルエミュレータのリリースを待ってます!いや、CMD.EXEぢゃなく・・・、いや、ホントに。

#2017年11月1日 追記
内容が古いので、ご注意ください。
また、Windows10 Fall Creators Updateから、マイクロソフトストアで複数のディストリビューションがダウンロードできるようになっているので、そちらを利用されることをおススメします。

ディストリビューションの切替は、wslconfig.exe コマンドを利用することを強く推奨します(^^;
従来からのものは、”Legacy”。 ストアからインストールされるものは、”Ubuntu”などとディストリビューション名で管理されているようです。
詳しくはこちら (English)


Bash On Windows、WSL(Windows Subsystem for Linux)で提供されているディストリビューションは ubuntu ですが、ubuntuの環境が動くんなら、他のディストリビューションも動くでしょ? というのが普通の感情(^^

ちょちょっとググってみると、やっぱりあります。
WSL Distribution Switcher ( https://github.com/RoliSoft/WSL-Distribution-Switcher )

Python3で書かれている一連のスクリプトツールのようですが、これを使うといろんなディストリビューションをインストールして切り替えて使えるようです! やったー!
ってなわけで、単純なオイラはすぐに Python の Windowsバイナリをインストールして、早速試してみました。

要するにこのツールは、LinuxディストリビューションのDockerイメージを取得・展開・切り替えの一連の手順をスクリプト化したもののようです。間違ってたらすみません。

で、結果的には、CentOSで運用できるところまではいかなかった・・・。いえ、一応CentOSをインストールできてbashは起動できたんですが・・・このエントリは、その時の備忘録です。

※ Pythonで書かれているので、Windows版のPython3バイナリをインストールしておく必要があります。cygwin環境のpythonだと dockerイメージの解凍に失敗してしまいました。この辺よく分かりません(m´・ω・`)m ゴメン…

上記サイトに行き、git 使っている方は、clone、使ってない方はzip書庫をダウンロードして適当なフォルダに展開してください。私は デスクトップに展開して作業しました。
ちなみに、Windows10のバージョンは Anniversary Update ( Windows10 v1607/Build14393 ) です。

まずは、README.mdに書かれている手順を行う前に、hook_postinstall_all.sample.sh というファイルをリネームして、hook_postinstall_all.sh にしときます。単に sample を消すだけです。
普通にインストールすると root のパスワードが設定されないので、困ることになるので、hook_postinstall_all.shを編集します。具体的には 下記の行をスクリプト上部のコメントが終わった直後ぐらいに追記しときます。

#rootのパスワード設定
ROOTPASSWD="0000"

前準備完了。

1、get-source.py で Docker Hub 内の オフィシャルイメージを取得します。

僕の目的は CentOSの最新版なので、単に centos と指定。 たぶん動かないと思うけど CentOS6系なら ‘centos:6’ というような感じで指定するみたいです。指定の仕方は docker のまんまですね・・・。詳しくは上記サイトのREADME.md 参照。

C:\Users\xxx\Desktop\WSL>> python get-source.py centos

これで tarボールがダウンロードできました。

2、install.py で tarボールの解凍および切り替え

ダウンロードしたtarボールを指定するか、イメージ名を引数にして install.py を実行。

C:\Users\xxx\Desktop\WSL>> python install.py centos

これで、%localappdata%\lxss ディレクトリにある既存のubuntuが入った rootfs がリネームされ、新しい rootfs に先ほどのイメージが格納されます。
その後、hook_postinstall_all.sh が実行されます。

これで一応インストール完了。試しに bash を立ち上げて、/etc/redhat-release を見ると

$ cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)

3、switch.py で切り替える

元の ubuntu に戻すときは、

C:\Users\xxx\Desktop\WSL>> python switch.py ubuntu:trusty

引数なしで実行すると、インストールされているディストリビューションの一覧が表示されます。

C:\Users\xxx\Desktop\WSL>> python switch.py
usage: ./switch.py image[:tag]

The following distributions are currently installed:

- centos:latest*
- ubuntu:trusty

To switch back to the default distribution, specify ubuntu:trusty as the argument.

4、sudo とかその他諸々がエラーで使えない!!!

さて、実はこれからです(笑)
CentOSがインストールされてやったー!と思って、以下のコマンドを叩くと・・・

$ sudo vi /etc/hosts
sudo: unable to create sockets: Socket type not supported

どうやら sudo コマンドが使えないみたい・・・。
README.mdには、その対策として、 alias sudo=”sudo -S” で回避するように、とのことですが、僕の環境だと同じエラーが出ます・・・。
仕方ないので、su でrootになって作業するしかありません・・・めんどくさーーーーーー!
他にも、localectl とか timedatectl とか なんちゃらctl が動かない。どーなっとんじゃー!?

ってな感じです。CentOS7自体まだ触ったことないんで・・・。ちなみに CentOS6はbash自体起動できず。まぁ、カーネルバージョンが違うので当たり前? これもよくわかんないです。

ってなわけで? おとなしく ubuntu に戻しました・・・。今後のWSLのアップデートに期待です・・・。次のWindows10のバージョンアップ( Creators Update でしたっけ?)でネットワーク関係のシステムコールがまともに使えるようになるんでしょうか・・・・???? 現状ネットワークドライブにアクセスできないので、まともに使えない・・・Apacheとかsambaとかフツーに使えるようにしてyo!!!

(m´・ω・`)m オネガイシマス。

CentOS6でシステムのHDDを入れ替える手順

(*)その後を書き足し。(2016/5/2)
(*)若干書き足し。(2016/3/2)
(*)ストレージのどちらかがMBRではなくGPTで初期化している場合おそらくこのエントリは役に立たないでしょう。(2019/5/20)

例によって、記録(備忘録)記事です。前置きがかなり長いです(m_m)

社内で使用しているテストサーバーは、Webアプリケーションの開発及び稼働チェック、社内マシンへのDNSサービス、ダミーのMTA、ソース管理(Subversion)サーバー、Sambaによるファイルサーバー等、僕が仕事する上で必要な機能がたった1つのマシンに集約されてます。というか、一台しか使わせて貰えない(^_^;;;

さらに、このマシンは10年前に買ってもらったCore2 Duo搭載のWindowsXPマシンだったものを社内のOSをXPからWindows7に一斉に変更するタイミングでWindows7へのアップグレードの対象外にされたもの。これを半ば強引に奪い取り(笑)、Linux(CentOS)を入れて今まで特に問題もなく、使用してきましたが、なんせ10年もHDD交換せずに稼働してきたので、そろそろHDDも寿命が尽きる頃。っていうか、もう十分寿命過ぎてる感があるのですが・・・。

HDDだけ新品に交換すれば十分ということで、内蔵HDDを経費として認めてもらえそうなので、仕事が一段落したらシステム移行することにした。

Windowsなら、ドライブごとコピー・・・とかすればいいんでしょうけど、Linuxではやったことないし、2つのHDDをLVMパーティションで作成して/,swap,/usr,/homeという風に分けて使っているのでそう単純にいかないことに気付く。かといって、クリーンインストールはできるだけ避けたい(やってる暇が無い・・・)

ってことで、前置きが長くなりましたが、実作業前に手順を記録して、VMWareで仮想マシンを一度作成しCentOSをインストール後、新しい仮想HDDを追加してHDD移行をシミュレートしてみました。

結果的に上手くいったので実作業前に移行手順を記録しておくことにした。でも正直これでいいのかどうか分からない。参考程度に見て頂くといいかもしれない。

一応分からないことはドキュメントを読んだり、ググったりしたけど、rsyncとかddとかfdiskとか、LVM関係とかの基本的なコマンドは普段殆ど使わないからオプションの指定の仕方とか合ってるかどうかわからん。

素人なりに考えた方法なので、たぶんもっとスマートな方法があるんだと思う。。。

※ パーティションの作成とかブートフラグをつける、等のfdiskやpartedコマンドの操作は省いています。それもできない、分からない、という人は大人しくクリーンインストールした方がいいと思う(逃げ)

(1)環境のチェック

現在のHDD構成 。使用率は20%ぐらい。1TBあるけどほとんど活用されていない。CentOSインストールするときRAID1構成にしようと思ったけど、はじめて仕事で使うサーバーだったので、知識ないのと、なんかあったら怖い、という理由でRAID1構成を諦めた経緯がある(ーー;

  • /dev/sda (500GB)
  • /dev/sdb (500GB)

新しいHDDは、500GB。このHDDに現在のHDDをシュリンクする。

  • /dev/sdc (500GB)

moving

現在のパーティション構成 (*bootable flag)
-------------------------------------------
/dev/sda1(*) Linux        => /boot

/dev/sda2    Linux LVM -+
                        | =>  /,/home,/usr,swap
/dev/sdb1    Linux LVM -+

現在のPV
-------------------------------------------
/dev/sda2  VolGroup lvm2 465.27G
/dev/sdb1  VolGroup lvm2 465.76G

現在のVG
-------------------------------------------
name: VolGroup

現在のLV
-------------------------------------------
lv_home VolGroup ext4 465.76G
lv_root VolGroup ext4  50.00G
lv_swap VolGroup swap   8.00G
lv_usr  VolGroup ext4 407.27G

(2)新しいHDDを現在のHDDと同じ構成にする。

 /dev/sdc1 => /boot 用
 /dev/sdc2 => LVMパーティション(/,/usr,/home,swap用)

作成した/boot用パーティション(/dev/sdc1)へ現在の/bootパーティション(/dev/sda1)をコピー。

 >> dd if=/dev/sda1 of=/dev/sdc1 bs=64MB

LVMパーティション/dev/sdc2にボリュームグループを作成する。
この際VolumeGroup名を現在のものとは別名(VolGroup01など)にする。
(現在のHDDを取り外した後、現在の名前にリネームするので)

 >> vgcreate VolGroup01 /dev/sdc2

この新しいVolumeGroup01から論理ボリューム(LV)を切り出していく(サイズは適当)

 >> lvcreate VolGroup01 -n lv_root -L 22GB 
 >> lvcreate VolGroup01 -n lv_swap -L 8GB 
 >> lvcreate VolGroup01 -n lv_usr -L 70GB 
 >> lvcreate VolGroup01 -n lv_home -l 100%Free
 各論理ボリューム上にファイルシステムを作成
 >> mkfs.ext4 /dev/VolumeGroup01/lv_xxxx (xxxxはroot,usr,home)

 スワップ用には
 >> mkswap /dev/VolumeGroup01/lv_swap

ここまでで、一旦シャットダウンする。

(3)インストールメディアから起動し、レスキューモードで立ち上げる。

(VolumeGroupがinactiveの場合はアクティベートする)
>> vgchange -a y 

(マウントポイント作成)
>> mkdir /mnt/src
>> mkdir /mnt/src/root
>> mkdir /mnt/src/home
>> mkdir /mnt/src/usr
>> mkdir /mnt/dest
>> mkdir /mnt/dest/root
>> mkdir /mnt/dest/home
>> mkdir /mnt/dest/usr

(論理ボリュームをマウントする)
>> mount /dev/VolGroup/lv_root /mnt/src/root
>> mount /dev/VolGroup/lv_home /mnt/src/home
>> mount /dev/VolGroup/lv_usr /mnt/src/usr
>> mount /dev/VolGroup01/lv_root /mnt/dest/root
>> mount /dev/VolGroup01/lv_home /mnt/dest/home
>> mount /dev/VolGroup01/lv_usr /mnt/dest/usr

(パーティションごとコピーする)
rsync -aHxv /mnt/src/root/ /mnt/dest/root
rsync -aHxv /mnt/src/home/ /mnt/dest/home
rsync -aHxv /mnt/src/usr/ /mnt/dest/usr

(コピーが終わったらマウントを解除して、後片付け)
>> umount /mnt/src/root
>> umount /mnt/src/home
>> umount /mnt/src/usr
>> rm -fr /mnt/src
>> umount /mnt/dest/root
>> umount /mnt/dest/home
>> umount /mnt/dest/usr
>> rm -fr /mnt/dest

(fdisk or parted コマンドで/dev/sdc1 にブートフラグを付ける)

ここで、poweroff (shutdown -h now)する。

(4) 一旦電源断して古いHDDを取り外し、再度レスキューモードで起動する

レスキューモードで起動する際の最終段階で、既存のLinuxインストールの探索をスキップしないように。スキップしてしまうと、せっかく上でコピーしたパーティションが/mnt/sysimageにマウントされないので)

ここまで来たらあとは、ボリュームグループのリネームとMBRのインストールするだけ。現在のHDDを取り外した後は、新しいHDDが /dev/sda と認識されるはずなので、ボリュームグループ名を元に戻す。.autorelabelファイルの作成は別にしなくてもいいかも。たぶんリブートしたら強制的にリラベルされるはず(僕が試したときはそうだった)

(ボリュームグループ名を旧HDDにあったものと同じにする)
>> vgrename VolGroup01 VolGroup

(grubインストール: MBRの復旧?)
>> chroot /mnt/sysimage
>> grub-install /dev/sda

(selinux relabel)
>> touch /.autorelabel

(5) インストールメディアを取り外し、リブートして起動を確認する。

ここで、起動に失敗したら、なんかおかしい事になってるので、もう一度HDDを古いものに接続しなおしてやりなおし(^^;;;;
とにかく一度仮想環境で手順を実際にやっておく方がいいと思う。
僕はWindows上のVMWareでHDD容量を1/20サイズでシミュレーションをしたらどうにか上手くいってシステム移行ができた。

(6)でも、ホントにこれで移行できるかどうか分からん

実機で、しかもLinuxで、のシステム環境移行ってやったことないので、デーモンがいろいろ動いていて実稼働しているシステムが本当に移行後上手く動いてくれるのかすんげぇ心配。

また、実際に実機でやってみて結果を追記する予定。でも・・・まだHDD買えてないんですけどね(^_^;;そもそも移行前にHDDが限界で壊れたらどうしよう・・・オロオロ (・_・ )( ・_・) オロオロ

(7) その後 2016年5月2日 追記

飛び石連休の最中、1日だけ出ても仕事は中途半端になるので、システム移行を決行。
HDDは、東芝製のバルクHDD(DT01ACA050)の500GBを買ってきて、PCに接続・・・ブートしない・・・orz
いろいろ試行錯誤した結果、元からあるHDDと新しく買ってきたHDD全部SATAポートに繋ぐと、ブートしないと判明。BIOS画面では一瞬認識するけど、すぐフリーズする。元からあるHDDとマザーボードはかなり古い機種なので混在するとダメなのかもしれないが、原因は不明。

仕方ないので、S-ATA ⇔ USB3 の変換コネクタを使用して新しいHDDをUSBストレージとして認識させた。コピーが遅くなるけど、仕方ない。

移行そのものは、スムーズに進行・・・と思いきや、(3)のrsyncでコピーする際、スラッシュを付け忘れているのに気付かず、(4)のレスキューモードで再起動した際、既存のLinuxシステムの検索に失敗したorz 。結局mvコマンドで1つ上のディレクトリに移動(^^;;;

最終的には上手くいきました。手順と理屈がある程度分かると、ツールを使ったHDD丸ごとコピーよりマニュアルでやる方が早いかも(^^)