---
# System prepended metadata

title: 從 BAK 檔還原 MSSQL 資料庫
tags: [MSSQL, SQL Server]

---

<style>
body, p, li, table {
    font-family: "Arial", "MingLiU";
}
h1, h2, h3, h4, h5, h6 {
    font-family: "Arial", "Microsoft YaHei";
}
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
    font-family: "Consolas";
}
pre, code {
    font-family: "MingLiU";
    white-space: pre-wrap !important;
    word-break: break-all !important;
}
.markdown-body pre {
    margin-bottom: 3px;
    padding: 10px 12px 6px 12px;
}
.markdown-body h6 code {
    font-size: 9pt;
    font-family: 'Arial';
    font-weight: normal;;
}
.div-font {
    font-family: "Arial", "MingLiU";
}
pre.fit {
    margin-top: -1em;
    margin-bottom: 0.5em;
}
pre.inline {
    display: inline;
    padding: 0.2em 0;
    margin: 0;
    line-height: 1.5;
}
pre.inline::before, pre.inline::after {
    content: "";
    display: inline-block;
    width: 0.3em;
}
pre.code-block {
    margin: -1em 0em 0.25em;
    font-size: 0.85em;
}
.markdown-body p+pre {
    margin-top: -12px;
    padding-top: 6px;
    margin-bottom: 0px;
}
code.inpara {
    display: inline-block;
    margin: 0.5em 0;
}
span.spnote {
    font-size: 0.85em;
    color: #f43;
}
span.spnote.add {
    color: #43f;
}
span.spnote a {
    color: #912;
}
span.refsrc {
    display: block;
    margin-top: -0.5em;
    margin-left: 1.5em;
    font-size: 0.75em;
    font-family: "Arial", "MingLiU";
}
.sp {
    color: #FF4000 !important;
}
a.private-note {
    color: indianred;
}
a.private-note:hover {
    color: firebrick;
}
.date-notes {
    font-size: 9pt;
    font-style: italic;
    color: gray;
    margin-bottom: 1em;
}
.lfis {
    margin-left: 1.5rem;
}
.lfid {
    margin-left: 2rem;
}
.smn {
    font-size: 0.8em;
    color: mediumslateblue;
    margin-right: 0.33em;
}
.ano {
    font-size: 0.9em;
    color: #f43;
}
i.emph {
    color: #d66;
}
i.empho {
    color: #93c;
}
.left-indent {
    margin-left: 2em;
}
strong, .emphasis {
    font-family: "Arial", "Microsoft YaHei";
    font-weight: bold;
}
strong code {
    font-family: "Consolas", "Microsoft YaHei";
}
.alert {
    margin-bottom: 0;
}
.alert-success a {
    color: #40b142;
}
.alert-warning a {
    color: #c19953;
}
.alert-danger a {
    color: #dc625f;
}
h6 div.timestamp {
    margin-top: 1rem;
}
</style>


# 從 BAK 檔還原 MSSQL 資料庫

###### Tags: `MSSQL` `SQL Server`


## 參考資料
* 實測經驗提供：Timmy Chao
* [還原資料庫的前置作業 | 積沙成塔 - 點部落](https://dotblogs.com.tw/terrychuang/2011/06/20/29262)

## 步驟
0. 設資料庫名稱為 <u>**agroup**</u>，BAK 檔名為 <u>**Backup.bak**</u>
1. 把 BAK 檔放進 SQL Server volume 可讀取的地方
   以下設我們存放 BAK 檔的路徑為 <u>**/var/opt/mssql/data/Backup.bak**</u>
2. 進入 SQL Server 容器，執行以下指令：
   ```bash
   touch /var/opt/mssql/data/agroup.mdf
   touch /var/opt/mssql/data/agrouplog.ldf
   chmod -R 777 /var/opt/mssql    # Docker volume 應已自動 777
   ```
3. 執行以下 SQL（可在 VSCode SQL Server (mssql) 插件的查詢窗中執行）：
   ```sql
   RESTORE FILELISTONLY FROM DISK = N'/var/opt/mssql/data/Backup.bak';
   ```
   以取得資料庫檔案（`.mdf` 與 `.ldf`）的實際名稱（**LogicalName 欄位**）
   例如這裡的 Backup.bak，其 LogicalName 分別為 **bpwms_pc_Data** 和 **bpwms_pc_Log**
4. 結合以上參數，執行以下 SQL 以實際還原資料庫：
   ```sql
   RESTORE DATABASE [agroup]
     FILE = N'bpwms_pc_Data'
     FROM 
       DISK = N'/var/opt/mssql/data/Backup.bak'
     WITH
       REPLACE,
       NOUNLOAD, 
       STATS = 5,
       FILE = 1, 
       MOVE N'bpwms_pc_Data'
         TO N'/var/opt/mssql/data/agroup.mdf',
       MOVE N'bpwms_pc_Log'
         TO N'/var/opt/mssql/data/agrouplog.ldf'
   ```
5. 最後再執行
   ```SQL
   ALTER DATABASE agroup SET AUTO_SHRINK OFF
   ```
   以關閉 agroup 資料庫的自動壓縮功能，以增進效能
6. **2022-06-08 補充：**
   經實測，現有的資料庫也可以用以上步驟直接還原
   注意不要在目標資料庫（如上面範例的 agroup）下跑，官方建議在系統資料庫 **master** 底下執行
   應該是直接覆蓋現有資料來還原（`REPLACE`），但這部分未實測

## 注意事項
* 宿主 CPU 為 ARM 架構（如 Apple M1 晶片）時，仍然可以跑 **mcr.microsoft.com/azure-sql-edge** 映像檔並建立 SQL Server 容器，但 PHP 目前尚無 for ARM 版本的 SQL Server driver，所以會報錯
  但據 Timmy 實測，在 Apple M1 上硬跑 AMD 架構的映像檔，雖然偶爾會 crash，但整體上還是能運行的
