迁移数据库到SQL on Linux Docker

问题引入

前一篇文章,菜鸟找到了SQL on Linux Docker容器销毁后,容器中的数据库文件可以得以保留的方法,老鸟非常开心。所以,今天又提出了新的问题:“鸟儿,如果我想把我的数据库从SQL on Windows迁移到SQL on Linux Docker,如何才能做到呢?”。
菜鸟一听这个问题,头脑迅速反应出数据库迁移的两种方法:备份还原和分离附加。就让我们来试试吧。详细的过程可以参见我录制的Youku视频:
12_SQLonLinux_Docker_Migration

构建SQL on Windows测试数据库

为了测试从SQL on Windows迁移数据库到SQL on Linux Docker的两种方法:备份还原和数据库附加。我们在SQL on Windows数据库实例中创建两个测试数据库,TestAttach和TestBackRestore,然后分别在两个数据库下创建一张测试表,接下来插入两条NEWID测试数据,最后查看这两条数据。

IF DB_ID('TestAttach') IS NULL
    CREATE DATABASE TestAttach;
GO

USE TestAttach
GO
IF OBJECT_ID('dbo.tb_Test', 'U') IS NOT NULL
    DROP TABLE dbo.tb_Test
GO

CREATE TABLE dbo.tb_Test(
RowID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY
,Name VARCHAR(36) NOT NULL
);

INSERT INTO dbo.tb_Test
SELECT NEWID() UNION ALL SELECT NEWID();

SELECT * FROM dbo.tb_Test;

IF DB_ID('TestBackRestore') IS NULL
    CREATE DATABASE TestBackRestore;
GO

USE TestBackRestore
GO
IF OBJECT_ID('dbo.tb_Test', 'U') IS NOT NULL
    DROP TABLE dbo.tb_Test
GO

CREATE TABLE dbo.tb_Test(
RowID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY
,Name VARCHAR(36) NOT NULL
);

INSERT INTO dbo.tb_Test
SELECT NEWID() UNION ALL SELECT NEWID();

SELECT * FROM dbo.tb_Test;

SELECT physical_name,* FROM sys.master_files
WHERE database_id = DB_ID('TestAttach');

执行结果截图如下:
迁移数据库到SQL on Linux Docker

为了可以直接复制mdf和ldf文件,我们需要下线数据库TestAttach,然后备份数据库TestBackRestore。

USE master
GO
ALTER DATABASE TestAttach SET OFFLINE;

USE master
GO
EXEC xp_create_subdir 'C:\temp\'
GO
BACKUP DATABASE [TestBackRestore] 
    TO DISK = 'C:\temp\TestBackRestore_full_20170210.bak' WITH STATS = 2 ;

传输数据库文件

由于我是在Mac系统安装Windows虚拟机来测试的,所以,首先我需要将Windows虚拟机中的文件复制到Mac系统。比如:我将下面三个文件复制到Mac的~/Downloads目录:

C:\SQL2K14_DATA\MSSQL12.MSSQLSERVER\MSSQL\DATA\TestAttach.mdf
C:\SQL2K14_DATA\MSSQL12.MSSQLSERVER\MSSQL\DATA\TestAttach_log.ldf
C:\temp\TestBackRestore_full_20170210.bak

接下来,我需要在Mac系统中,将这三个文件复制到SQL on Linux Docker容器中,方法如下:

docker cp ~/Downloads/TestAttach.mdf linuxsql41433:/var/opt/mssql/data/TestAttach.mdf
docker cp ~/Downloads/TestAttach_log.ldf linuxsql41433:/var/opt/mssql/data/TestAttach_log.ldf
docker cp ~/Downloads/TestBackRestore_full_20170210.bak linuxsql41433:/var/opt/mssql/data/TestBackRestore_full_20170210.bak

备份文件、数据库数据文件和日志文件准备完毕后,接下来该是还原数据库和附加数据库了。

还原数据库到SQL on Linux Docker

这个和SQL on Windows还原操作没有什么两样,思路还是先检查备份文件的完整性,然后使用Restore语句还原数据库。使用SSMS连接到SQL on Linux Docker中,执行以下脚本:

USE master
GO
--Verify backup file
RESTORE FILELISTONLY 
    FROM DISK = N'C:\var\opt\mssql\data\TestBackRestore_full_20170210.bak';
RESTORE VERIFYONLY 
    FROM DISK = N'C:\var\opt\mssql\data\TestBackRestore_full_20170210.bak';
-- Restore Database
USE master
GO
RESTORE DATABASE [TestBackRestore]
FROM DISK = N'C:\var\opt\mssql\data\TestBackRestore_full_20170210.bak'
WITH MOVE N'TestBackRestore' TO N'C:\var\opt\mssql\data\TestBackRestore.mdf'
    ,MOVE N'TestBackRestore_log' TO N'C:\var\opt\mssql\data\TestBackRestore_log.ldf'
    ,STATS=2
GO

最后是附加数据库到SQL on Linux Docker的操作。

附加数据库到SQL on Linux Docker

附加数据库方法也和SQL on Windows一样,使用Create Database for Attach方法。同样,使用SSMS连接到SQL on Linux Docker,执行以下数据库附加操作脚本:

USE master
GO
-- Create database via attach
CREATE DATABASE [TestAttach]
    ON ( FILENAME = N'C:\var\opt\mssql\data\TestAttach.mdf'),
    ( FILENAME = N'C:\var\opt\mssql\data\TestAttach_log.ldf')
    FOR ATTACH;
GO

最后确认

最后确认操作,只需要检查下这两个数据库下的测试表数据是否和迁移之前一致即可。

SELECT * FROM TestAttach.dbo.tb_Test;
SELECT * FROM TestBackRestore.dbo.tb_Test;

对比迁移前后数据库测试表中的数据是否一致:
迁移数据库到SQL on Linux Docker

从最后的确认结果来看,迁移前后的数据库测试数据完全一致,本次迁移数据使用的两种方法都是成功的,可靠的。

写在最后

SQL on Windows上的数据库,可以非常平滑的迁移到SQL on Linux Docker中来,这个是Windows版和Linux版数据库可以任意选择的前提。我们可以使用数据库的备份还原和分离附件两种方法来达到数据库迁移的目的。

上一篇:版本管理三国志 (CVS, Subversion, git)


下一篇:Day2笔记——身份证识别系统搭建