I'm attempting to restore a backup on many remote machines - each of which have a local
.BAK file. This is being done from within a PS workflow:
foreach -parallel ($server in $targetServers)
$serverName = $using:server.serverName;
$serverDrive = $using:server.drive;
$bakFileName = $using:testBakFileName;
$targetFileFullPath = "\\$servername\$serverDrive\$bakFileName";
"ALTER DATABASE $using:TargetDbName SET Single_User WITH Rollback Immediate
RESTORE DATABASE $using:TargetDbName FROM DISK = N'$targetFileFullPath' WITH FILE = 1, NOUNLOAD, REPLACE, STATS = 10
ALTER DATABASE $using:TargetDbName SET MULTI_USER"
Write-Output " Restoring $using:TargetDbName from $targetFileFullPath on $serverName with $sqlScript"
Invoke-Sqlcmd -Query "$sqlScript" -Verbose -queryTimeout 65534
This seems to work if I do one at a time, but if I run multiple in parallel, I get a deadlock error:
Invoke-Sqlcmd : Exclusive access could not be obtained because the database is in use.
RESTORE DATABASE is terminating abnormally.
Transaction (Process ID 54) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
ALTER DATABASE statement failed.
What am I doing wrong?
Based on the SQL error alone, it appears that the RESTORE DATABASE command is being called more than once on one of your remote servers. Run that script, but comment out the Invoke-Sqlcmd line. Examine the list of servers and see if you are restoring a database more than once on a server.
Otherwise, have you tried running the PS script without the parallel option? In other words, will a regular for each succeed? If so, then your problem is in the syntax of your parallel operation. I've never used PowerShell parallel processing myself, but it appears to have some unexpected behavior: Reddit discussion