SQL Server xp_delete_file not deleting files

2020-02-09 03:55发布

问题:

I'm trying to write some SQL that will delete files of type '.7z' that are older than 7 days.

Here's what I've got that's not working:

DECLARE @DateString CHAR(8)
SET @DateString = CONVERT(CHAR(8), DATEADD(d, -7, GETDATE()), 1)
EXECUTE master.dbo.xp_delete_file 0, 
                  N'e:\Database Backups',N'7z', @DateString, 1

I've also tried changing the '1' a the end to a '0'.

This returns 'success', but the files aren't getting deleted.

I'm using SQL Server 2005, Standard, w/SP2

回答1:

Had a similar problem, found various answers. Here's what I found.

You can't delete 7z files with xp_delete_file. This is an undocumented extended stored procedure that's a holdover from SQL 2000. It checks the first line of the file to be deleted to verify that it is either a SQL backup file or a SQL report file. It doesn't check based on the file extension. From what I gather its intended use is in maintenance plans to cleanup old backups and plan reports.

Here's a sample based on Tomalak's link to delete backup files older than 7 days. What trips people up is the 'sys' schema, the trailing slash in the folder path, and no dot in the file extension to look for. The user that SQL Server runs as also needs to have delete permissions on the folder.

DECLARE @DeleteDate datetime
SET @DeleteDate = DateAdd(day, -7, GetDate())

EXECUTE master.sys.xp_delete_file
0, -- FileTypeSelected (0 = FileBackup, 1 = FileReport)
N'D:\SQLbackups\', -- folder path (trailing slash)
N'bak', -- file extension which needs to be deleted (no dot)
@DeleteDate, -- date prior which to delete
1 -- subfolder flag (1 = include files in first subfolder level, 0 = not)

Note that xp_delete_file is broken in SP2 and won't work on report files; there's a hotfix for it at [http://support.microsoft.com/kb/938085]. I have not tested it with SP3.

Since it's undocumented, xp_delete_file may go away or change in future versions of SQL Server. Many sites recommend a shell script to do the deletions instead.



回答2:

AFAIK xp_delete_file only delete files recognized by SQL Server 2005 (backup files, transaction logs, ...). Perhaps you can try something like this:

xp_cmdshell 'del <filename>'


回答3:

This sp will only delete native sql server backup files or native maintenance report files (for security purposes)

As Smink suggested you can use

xp_cmdshell 'del <filename>'

With the proper permissions on the folder.



回答4:

I found this question, but the solution didn't apply to me (as it was .bak files, SQL Server itself had made, as part of a Maintenance Plan).

The issue in my case was security. The script was being run as the user which starts SQL Server (MSSQL) (in my case and probably most cases "network service") didn't have access to the folder it was trying to delete files in.

So adding "network service" and granting it "modify" helped.



回答5:

I had read many different approaches and solutions multiple individuals pursued when attempting to resolve the issue with the extended stored procedure xp_delete. The solutions are:

  1. Be sure to NOT have a period (.) in the extension when configuring the SSIS maintenance task.
  2. Be sure to click on the Include First-Level sub folders if they exist for each database backup.
  3. Be sure to click on the backup files at the top. The maintenance task does check the file type. For database backups, I believe it checks the backup file header.

In my scenario, all of the above were correct. There are few comments on the web where some of said the routine xp_delete is buggy.

When the backup files were not being deleted, I extracted the SQL for the maintenance and ran it from SSMS. The resulting message was the file was not a sql server backup file. This message was erroneous as the backup could be restored successfully, resulting in an operational database.

The database commands used to verify the database were:

RESTORE HEADERONLY FROM DISK = N'<file path\filename>.Bak'
RESTORE VERIFYONLY FROM DISK = N'<file path\filename>.bak'

Both of the above commands indicated the backup file was valid.

Next I opened the event viewer and found messages indicating there were login errors for the connection manager. This was strange because I had validated the connection with the test connection button. The errors were not related to any account I had created.

Event Viewer Message:

*The description for Event ID 17052 from source MS SQL SERVER cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer. If the event originated on another computer, the display information had to be saved with the event.

The following information was included with the event:

Severity: 16 Error:18456, OS: 18456 [Microsoft][SQL Server Native Client 11.0][SQL Server]Login failed for user 'domain\servername$'.*

Next I logged onto a machine where xp_delete was functioning correctly. After reviewing the active directory and not finding the system account, I proceeded to the event viewer to find similar messages. Here it became evident the account for domain\server$ is mapped to system security.

Next step was to compare the database security where xp_delete worked against the database where it did not work. There were 2 missing logins under security in the database where xp_delete did not work. The 2 missing logins were: NT AUTHORITY\SYSTEM NT Service\MSSQLSERVER

After adding NT service\MSSQLSERVER, xp_delete successfully worked.

One approach to testing is to use the maintenance task to delete an individual file.



回答6:

Try changing the first parameter from 0 to 1.

Here is a small summary on xp_delete_file I just found. Sounds a bit like you'd be out of luck with this procedure.



回答7:

I know this is a little old but I wanted to share my frustrations with you all. I was having the same problem as a lot of these posts but nothing seemed to work. I then remembered that we have an encryption layer on the database called NetLib. This means that the backups are encrypted and as such, xp_delete_file cannot read the headers. I now use a batch file in the OS and call it from an agent job. Hope this helps someone.



回答8:

We usually end up in such situations when you have the database moved to another server or when a SQL instance is reinstalled on the same one but the backup is left in the old directory. For example: You move the database from server1 to server2, but you have a server with a maintenance plan which performs a periodic backup or you reinstall the SQL instance on server1 and you restore the database.

In the backup case the sets which are kept as information in msdb are no longer there, therefore all older backups which have been created will not be deleted as no information is checked from the fails derived from the tables with backup sets.

EXECUTE master.sys.xp_delete_file  0, -- FileTypeSelected (0 = FileBackup, 1 = FileReport)

The first argument shows that the tables from msdb are being used.

Hope this helps someone.