Sql-Server

SQL Azure 遷移嚮導 - 重複主鍵

  • October 19, 2016

剛剛在使用SQL Azure 遷移嚮導將 120gb 數據庫遷移到 RDS 上進行了測試

因為我們不能為“僅僅”一個測試而承受任何停機時間,所以我們在實時數據庫上執行該工具(這意味著在該工具執行時數據仍在被插入/更新/刪除)

腳本創建正常,但在插入數據期間出現錯誤“BCP 複製失敗”“無法插入重複鍵”

我的直覺是因為在創建 .dat 文件時數據是實時的,它以某種方式讀取了同一行兩次,但我真的不想做出一個假設,當我們進行真正的遷移時,我可能會後悔,當數據庫將顯然是離線的。

發生這種情況還有其他原因嗎?我可以假設我在“重要日子”使用只讀數據庫的工具是安全的嗎?

- 更新 -

我們再次嘗試執行失敗的表的完全相同的 .dat 文件並且它有效。這似乎表明重複的密鑰不在腳本中……我更加困惑,這可能是工具中的錯誤嗎?

我在嘗試使用 SQL 遷移嚮導創建數據庫的本地副本時遇到了同樣的問題。我知道我的源數據沒有重複的鍵值,所以我想出了以下腳本。它只會導致忽略重複的鍵條目(並生成警告而不是錯誤)。請閱讀下面程式碼塊中的註釋以獲取說明。

-- For some reason, SQL Azure Migration Wizard tries to insert duplicate records and fails.
-- I've wasted a lot of time making many many many attempts at copying the database, failing repeatedly, 

-- So this is the workaround:
-- 1.0 In SQL Azure Migration Wizard: After selecting the database to script, select the "Advanced" button.
-- 1.1 Change the "Script Table / Data" property from "Table Schema with Data" to "Table Schema Only".
-- 1.2 Click "Next" and proceed until the "Schema Only" migrate script has been executed a new database. 

-- 2. Run THIS Sql script with @IGNORE_DUP_KEY set to 'ON' against the TARGET database.

-- 3.0 Back in SQL Azure Migration Wizard, click "Back" until you see the advanced button again, and click it.
-- 3.1 Change the "Script Table / Data" property from "Table Schema with Data" to "Data Only".
-- 3.2 Click "Next" and proceed until the script has been executed.  NOTE: Table Name may still appear red like it failed, but looking at the message will show you that it was just a warning.  
--     TO VERIFY: "SELECT COUNT(*) FROM TableName" on any tables that had the warning show in the source and target databases, and compare the counts.

-- 4. Run THIS Sql script, but set @IGNORE_DUP_KEY to 'OFF' to revert back to original/expected behavior.
DECLARE @IGNORE_DUP_KEY VARCHAR(MAX) = 'ON'; -- Options: ON, OFF

DECLARE @TableName VARCHAR(255)
DECLARE @sql NVARCHAR(500)

DECLARE TableCursor CURSOR FOR
SELECT OBJECT_SCHEMA_NAME([object_id])+'.'+name AS TableName
FROM sys.tables

OPEN TableCursor

FETCH NEXT FROM TableCursor INTO @TableName
WHILE @@FETCH_STATUS = 0
   BEGIN
       SET @sql = 'ALTER TABLE ' + @TableName + ' REBUILD WITH (IGNORE_DUP_KEY = ' + @IGNORE_DUP_KEY + ');'
       --print @sql
       EXEC (@sql)

       FETCH NEXT FROM TableCursor INTO @TableName
   END

CLOSE TableCursor
DEALLOCATE TableCursor

GO

我知道這個解決方案是在提出原始問題後一段時間發布的,但希望這會幫助其他人!

如果您的第一次測試顯示有問題,請假設存在問題!

問題不會在生產中消失,即使你有最好的理論來證明它們的存在,你仍然需要測試。

預設情況下, BCP 副本應使用行級鎖。由於數據的大小,

這應該升級到頁面級鎖定。

如果儘管有這些鎖,您仍然得到重複的 ID,則 BCP 實用程序獲得的數據的一致性有問題。identity_insert觸發器

可能存在問題。但是如果沒有看到數據和表結構就很難說。

您真的應該使用生產數據庫的副本再次測試,沒有理由使用實時數據庫對其進行測試。

如果有的話,您的第一次測試失敗應該是您的經理允許您進一步測試的充分動力。

引用自:https://dba.stackexchange.com/questions/111531