FTPにCSVを始めとしたテキストベースのファイルをアップロード・ダウンロードした場合にファイルの文字コードが変わってしまう事があります。 その原因と対処法を紹介したいと思います。 改行コードが変わる…
やりたいこと
DockerHubから取得したMicrosoft Linux版のSQL Serverで、Windows上のディレクトリを永続化のためにマウントして、バックアップデータ(.bak)からデータベースを復元する。
Dockerでマウントされているディレクトリに復元しようとすると、上手くいかなかったので解決方法を含めて手順をメモしておく。
環境
- Windows 10 Pro
- Docker Desktop (Docker 19.03.13)
- Image: mcr.microsoft.com/mssql/server 2019-CU8-ubuntu-16.04
手順
ディレクトリ情報
C:\bak
復元するためのバックアップデータ(.bak)を保存C:\mssql
コンテナ内のMSSQLのデータ保存先にマウントして永続化するディレクトリ
コンテナを起動する
上2つのディレクトリをマウントする。
Docker Desktopがこのディレクトリを共有するのか?って聞いてくるので、Yes
とすると、Docker DesktopのSettings > Resources > FILE SHARING
に追加してくれる。
docker run --name mssql -itd -v "c:\bak\":/bak -v "c:\mssql":/var/opt/mssql -p 1433:1433 -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=<Password>' mcr.microsoft.com/mssql/server:2019-latest
SSMS (SQL Server Management Studio)から復元する
手っ取り早くWindowsのSSMSからGUIで復元操作を行う。
※コンテナに入って直接コマンドで行ってもOK
ハマりポイント
普通に復元しようとすると、復元すると生成されるmdfやldfがないぞとエラーが投げられる。
/var/opt/mssql/data
に対するmssql
ユーザーはフルアクセス権があるにも関わらず表示され、GitHubではバグだと騒がれている(MSSQL 2019 Database Restore Fails)
メッセージ 3634、レベル 16、状態 1、行 2
The operating system returned the error '2(The system cannot find the file specified.)' while attempting 'RestoreContainer::ValidateTargetForCreation' on '/var/opt/mssql/data/<Database Name>.mdf'.
メッセージ 3156、レベル 16、状態 5、行 2
File '<Database Name>' cannot be restored to '/var/opt/mssql/data/<Database Name>.mdf'. Use WITH MOVE to identify a valid location for the file.
メッセージ 3634、レベル 16、状態 1、行 2
The operating system returned the error '2(The system cannot find the file specified.)' while attempting 'RestoreContainer::ValidateTargetForCreation' on '/var/opt/mssql/data/<Database Name>_log.ldf'.
メッセージ 3156、レベル 16、状態 5、行 2
File '<Database Name>_log' cannot be restored to '/var/opt/mssql/data/<Database Name>_log.ldf'. Use WITH MOVE to identify a valid location for the file.
メッセージ 3119、レベル 16、状態 1、行 2
Problems were identified while planning for the RESTORE statement. Previous messages provide details.
メッセージ 3013、レベル 16、状態 1、行 2
RESTORE DATABASE is terminating abnormally.
新しく空っぽのデータベースを作成してから、そこに既存のデータベースを上書きする
REPLACEオプションを付けて復元すると上手くいくらしいので実行する。
USE [master]
RESTORE DATABASE [<Database Name>] FROM DISK = N'/bak/database.bak' WITH FILE = 1, MOVE N'<Database Name>' TO N'/var/opt/mssql/data/database.mdf', MOVE N'<Database Name>_log' TO N'/var/opt/mssql/data/database_log_1.ldf', NOUNLOAD, REPLACE, STATS = 5
GO
さっきとは違うエラーが投げられる。
メッセージ 3634、レベル 16、状態 1、行 2
The operating system returned the error '2(The system cannot find the file specified.)' while attempting 'RestoreContainer::ValidateTargetForCreation' on '/var/opt/mssql/data/<Database Name>_log_1.ldf'.
メッセージ 3156、レベル 16、状態 5、行 2
File '<DATABASE NAME LOG>' cannot be restored to '/var/opt/mssql/data/<Database Name>_log_1.ldf'. Use WITH MOVE to identify a valid location for the file.
メッセージ 3119、レベル 16、状態 1、行 2
Problems were identified while planning for the RESTORE statement. Previous messages provide details.
メッセージ 3013、レベル 16、状態 1、行 2
RESTORE DATABASE is terminating abnormally.
バックアップファイルを作ったSSMSのバージョンの違いからか、生成される復元クエリを見るとログのldfファイル名の末尾に_1
が自動的に付与されている。
これでは、新しく作ったデータベースのログは<Database Name>_log.ldf
なので、上書きではなく新規作成になってしまう。
今回は新規作成が出来ずにこけている。
上書きされるように末尾の_1
を削除して再実行して、復元されることを確認した。
なぜ、mssqlユーザーに書き込み権限があるのに書き込めないのかは不明。
GitHubでは前まで出来てたのにバージョン上げたら出来なくなった、バグだ!って騒がれてる。
(ほんとに?)
WindowsやC#の技術者ってLinux嫌い苦手なのか、情報が少ない気がする…(偏見)
コマンドメモ
コンテナに入る
docker exec -it mssql bash
コンテナ内でクエリを実行する
コンテナに入った状態でsqlcmd
を実行する。
Microsoftが配布しているイメージにはsqlcmdはインストール済みだけどパス設定がされていないのでフルパスで実行する。
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "<Password>"
コメントを書く