SQL Azure 遷移嚮導 - 重複主鍵
剛剛在使用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觸發器
可能存在問題。但是如果沒有看到數據和表結構就很難說。
您真的應該使用生產數據庫的副本再次測試,沒有理由使用實時數據庫對其進行測試。
如果有的話,您的第一次測試失敗應該是您的經理允許您進一步測試的充分動力。