<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,但整體上還是能運行的