使用 Docker 執行 SQL Server on Linux 容器之常用工具與命令 | The Will Will Web

The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

使用 Docker 執行 SQL Server on Linux 容器之常用工具與命令

最近因為正在進行【ASP․NET Core 3 開發實戰:從入門到進階】課程,上課的學員中使用 macOS 來學習 .NET Core 的人越來越多,當練習到 ASP․NET Core 搭配 Entity Framework Core 的時候,因為會用到 SQL Server 進行練習,所以本篇文章將分享如何利用 Docker 執行 SQL Server on Linux 容器,並分享幾個常用的工具命令與使用範例。

下載 SQL Server 2019 容器映像 (docker pull)

從 SQL Server 2019 CU3 開始,已經支援 Ubuntu 18.04 版本。
從 SQL Server 2019 CU10 開始,已經支援 Ubuntu 20.04 版本。

你可以透過以下命令下載容器映像:

sudo docker pull mcr.microsoft.com/mssql/server:2019-latest

目前從 Microsoft SQL Server - Docker Hub 可以查到的 image tag 比較舊,反而從 Quickstart: Run SQL Server container images with Docker 官方文件可以查到最新版本。

如果想下載 RHEL-based 容器映像,可以查閱這份文件說明。

sudo docker pull mcr.microsoft.com/mssql/rhel/server:2019-CU1-rhel-8

執行 SQL Server 2019 容器 (docker run)

以下是 docker run 使用範例:

sudo docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=Ver7CompleXPW" \
  -p 1433:1433 --name sql1 \
  -d mcr.microsoft.com/mssql/server:2019-latest

設定 SA_PASSWORD 的時候必須符合密碼複雜性要求:

  • 密碼不包含使用者的帳戶名稱,也就是不能包含 sa 這個字。
  • 密碼長度至少為 8 個字元,密碼長度最多可達 128 個字元。
  • 密碼包含下列四種類別的其中三種:
    • 拉丁文大寫字母 (A 到 Z)
    • 拉丁文小寫字母 (a 到 z)
    • 以 10 為基底的數字 (0 到 9)
    • 非英數字元,例如:驚嘆號 (!)、錢幣符號 ($)、數字符號 (#) 或百分比符號 (%)

執行容器實際範例

sudo docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=Ver7CompleXPW" -p 1433:1433 --name sql1 -d mcr.microsoft.com/mssql/server:2019-latest

進入容器執行

  • 進入容器 bash 環境

    sudo docker exec -it sql1 "bash"
    

    容器中 sqlcmd 工具的路徑為 /opt/mssql-tools/bin/sqlcmd

  • 變更 SA 帳號密碼

    由於預設的 SA 帳戶密碼是透過環境變數 SA_PASSWORD 傳入的,你只要進入 bash 執行 ps -eax | catset 就可以看到密碼。基於安全理由,你可以透過以下命令變更 SA 密碼:

    sudo docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd \
      -S localhost -U SA -P "Ver7CompleXPW" \
      -Q 'ALTER LOGIN SA WITH PASSWORD="YourNewStrong@Passw0rd"'
    
  • 進入 sqlcmd 互動模式

    sudo docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd -U SA -P Ver7CompleXPW -W
    

    上述命令的 -W (大寫 W 字母) 選項會從資料行中移除尾端的空格,否則通常執行結果很難閱讀。

    SQLCMD 中執行 T-SQL 最後要輸入 GO 命令才會執行。

    例如你想查詢當前執行的 SQL Server 版本,就要輸入以下命令:

    SELECT @@VERSION
    GO
    

    如果要退出 sqlcmd 互動模式,請輸入以下命令:

    QUIT
    
  • 直接從本機連接 SQL Server 容器

    由於我們執行 SQL Server 容器時,已經加上 -p 1433:1433 參數,因此你可以從本機的 localhost:1433 連接容器中的 SQL Server 服務。

    如果你的本機已經有安裝 SQL Server 任意版本,通常會包含 sqlcmd 用戶端工具,當你使用 -S 參數指定伺服器名稱時,要加上 Port 埠號必須用 localhost,1433 這種格式,主機名稱與埠號之間是用「逗號」分隔喔!

    sqlcmd -S localhost,1433 -U SA -P "Ver7CompleXPW" -W
    

常見 T-SQL 查詢

  • 列出資料庫清單

    sudo docker exec sql1 /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "Ver7CompleXPW" -W -Q "SELECT name FROM sys.databases"
    
  • 批次執行 T-SQL 命令 (例如:匯入資料庫)

    # 下載 ContosoUniversity.sql 檔案
    curl -o ContosoUniversity.sql https://gist.githubusercontent.com/doggy8088/2a2f7075d49b3814d19513426ede3549/raw/ab95b323425ff98e99b901793d0361d90439fb0b/ContosoUniversity.sql
    # 複製檔案進 sql1 容器
    sudo docker cp ContosoUniversity.sql sql1:/
    # 批次執行指定的 T-SQL 檔案
    sudo docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "Ver7CompleXPW" -i ContosoUniversity.sql
    
  • 建立資料庫

    假設資料庫名稱為 test1,你可以用以下命令建立一個空資料庫:

    sudo docker exec sql1 /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "Ver7CompleXPW" -W -Q "CREATE DATABASE [test1]"
    
  • 啟動容器並還原資料庫

    以下命令可以在 WSL 2 環境執行:

    # 準備還原指令碼
    cat <<EOF > restore.sql
    -- 請記得先修改備份檔實體路徑
    USE [master]
    RESTORE DATABASE [mydb] FROM  DISK = N'/var/opt/mssql/backup/mydb.bak' WITH  FILE = 1,
    MOVE N'mydb'     TO N'/var/opt/mssql/data/mydb_Primary.mdf',
    MOVE N'mydb_log' TO N'/var/opt/mssql/data/mydb_Primary.ldf',  NOUNLOAD,  STATS = 5
    GO
    -- 清空交易記錄 (開發環境不需要)
    ALTER DATABASE [mydb] SET RECOVERY SIMPLE WITH NO_WAIT
    GO
    -- 壓縮資料庫
    DBCC SHRINKDATABASE(N'mydb')
    GO
    EOF
    
    # 啟動容器並將 /mnt/c/TEMP/DB 掛載到容器的 /var/opt/mssql/backup 目錄下
    sudo docker run --name sql1 -p 1433:1433 \
        -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Ver7CompleXPW' \
        -v '/mnt/c/TEMP/DB:/var/opt/mssql/backup' \
        -d mcr.microsoft.com/mssql/server:2019-latest
    
    # 查看容器啟動紀錄 (確保服務已正常啟動)
    sudo docker logs sql1 -f
    
    # 還原資料庫 (其中包含截斷交易記錄與壓縮資料庫)
    sudo docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'Ver7CompleXPW' -i '/var/opt/mssql/backup/restore.sql' -e
    
    # 查看資料檔大小
    sudo docker exec -it sql1 bash -c 'ls -l /var/opt/mssql/data/mydb*'
    
  • 備份資料庫

    以下命令可以在 WSL 2 環境執行:

    # 準備備份指令碼
    cat <<EOF > backup.sql
    BACKUP DATABASE [mydb]
    TO  DISK = N'/var/opt/mssql/backup/mydb.bak' WITH COPY_ONLY, FORMAT, INIT,
    NAME = N'mydb-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,
    COMPRESSION, STATS = 10
    GO
    EOF
    
    # 備份資料庫 (包含壓縮備份檔)
    sudo docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'Ver7CompleXPW' -i '/var/opt/mssql/backup/backup.sql' -e
    
  • 刪除資料庫

    假設資料庫名稱為 test1,你可以用以下命令刪除資料庫:

    sudo docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "Ver7CompleXPW" -Q "DROP DATABASE [test1]"
    

    如果資料庫因為還有既有連線而無法刪除,可以改用以下命令:

    sudo docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "Ver7CompleXPW" -Q "ALTER DATABASE [test1] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [test1]"
    

相關連結