SQL Server: Incorrect PFS free space information for page (1:xxxx) in object ID xxxxxx:

udayarumilli_pfs

SQL Server: Incorrect PFS free space information for page (1:xxxx) in object ID xxxxxx:

 

“Incorrect PFS free space information for page (1:233791) in
object ID 367392428, index ID 1, partition ID 72057594180730880, alloc unit ID 72057594222018560 (type LOB data). Expected value   0_PCT_FULL, actual value 100_PCT_FULL.  CHECKDB found 0 allocation errors and 1 consistency errors in table ‘xxxxxxx’ (object ID 367392428).

 

We have a maintenance plan which is scheduled to run on weekly basis and checks the database integrity for specified user databases in production instance.

 I found above error in SQL Server log. Clearly from the error message we can say that it’s not the page corruption. There is a special page called PFS (Page Free Space) which indicates the percentage of page full. It actually helps free space scanner while inserting data.

In this case PFS is 100% means it indicates page is full whereas in real the page is empty.  DBCC commands will fail due to this wrong calculation.

Resolution:

To resolve this I have tried the below procedure.
  1. Take a full backup of the database (Based on the size if it’s a huge DB take the backup of table just by using “SELECT * INTO <bkp_table> FROM <corrupted_table>)
  2. From sql log we can find the object (Table/Index) name and ID
  3. Put database in single user mode
ALTER DATABASE <Corrupted_Table_DatabaseName>
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE

 

  1. Run DBCC CHECKTABLE() on specific table / index
DBCC CHECKTABLE(<Corrupted_Table>) WITH ALL_ERRORMSGS;
  1. It will reproduce the “PFS” error.
  2. To fix this execute the below two statements one after other.
DBCC CHECKTABLE(<Corrupted_Table>,REPAIR_FAST) WITH ALL_ERRORMSGS;
GO
DBCC CHECKTABLE(<corrupted_table>,REPAIR_REBUILD) WITH ALL_ERRORMSGS;

 

  1. For most of the cases the problems must be fixed with above two checks.
  2. If not goahead and execute the below statement
DBCC CHECKTABLE(<Corrupted_Table>,REPAIR_ALLOW_DATA_LOSS) WITH ALL_ERRORMSGS;


  1. For first time it executes and completes with the same PFS error message.
  2. Re execute the step number 8, now this time it fix the issue and avoid the PFS error.
  3. Put database in multi user mode

 

ALTER DATABASE <Corrupted_Table_DatabaseName> SET MULTI_USER;

 

If it’s not got resolved, put the database in single user mode, backup the corrupted table (using SELECT * INTO <bkp_table>) . Backup the table creation script with all key relationships, drop the corrupted table, rename the backup table with the original table and recreate all keys and relationships.
If it still not gets resolved there is only option. Restore the database with the latest possible backup.
Posted in SQL Server DBA | Tagged , , , , , , , , , , | 3 Comments

SQL Server database backup automation using T-SQL

robot with computer and stethoscope

SQL Server database backup automation using T-SQL

I have gone through a request as a part of daily maintenance. Found a backup maintenance plan has been failed due to low disk space.

 “SQL Task     Description: Executing the query “BACKUP DATABASE CA1011_DB TO DISK = …” failed with the following error: “A nonrecoverable I/O error occurred on file “C:\Backup\ CA1011_DB \ CA1011_DB _backup_2013_06_05_010000_7196421.bak:” 112(There is not enough space on the disk.).  BACKUP DATABASE is terminating abnormally.”

 We have designed a maintenance plan that performs backup for all selected databases, once after backup a task added to cleanup the backup files. But the problem is while performing backup all previous day backups are still available on folders and those can be deleted only after backup job completed.

 So for all databases if the total backup size is 200 GB we exactly need 400GB free space on drive. To avoid these issues we have created a T-SQL script which performs backup and clean up the old backup.

 Existing Maintenance Plan:

 Step1: Perform backup for Database-1

Step2: Perform backup for Database-2
—————————————————-
—————————————————-
StepN: Perform backup for Database-N
StepN+1: Delete the previous day backup from all folders

 

New T-SQL Script:

SQL Server database backup automation using T-SQL

 Step1: Perform backup for Database-1

Step2: Deletes previous day backup for Database-1

Step3: Perform backup for Database-2

Step4: Deletes previous day backup for Database-2

—————————————————-

—————————————————-

StepN: Perform backup for Database-N

StepN+1: Deletes previous day backup for Database-N

 Below is the script to perform a backup and deletes previous days backup.

 

USE MASTER;
GO

IF EXISTS(SELECT 1 FROM SYS.SYSOBJECTS WHERE NAME = 'usp_Backup_Database' AND TYPE='P')
BEGIN
	DROP PROCEDURE [usp_Backup_Database];
END
GO
CREATE PROCEDURE usp_Backup_Database (
				@db_nameNVARCHAR(50),
				@file_pathNVARCHAR(256))
AS
BEGIN
SET NOCOUNT ON
DECLARE	@fileName	NVARCHAR(256);-- Filename for backup
DECLARE	@fileDate	VARCHAR(20);-- Used for file name
DECLARE	@DeleteDate	DATETIME = GETDATE();-- Cutoff date

-- Get date to include with the file name.
SELECT @fileDate = CONVERT(VARCHAR(20),GETDATE(),112);

-- Build the file path and file name.
SET @fileName = @file_path + @db_name + '_' + @fileDate + '.BAK';

-- Backup the database.
BACKUP DATABASE @db_name TO DISK = @fileName WITH INIT;

-- Delay 10 sec
WAITFOR DELAY'000:00:10';

-- Purge old backup files from the disk.
EXEC master.sys.xp_delete_file 0,@file_path,'BAK',@DeleteDate,0;

END
GO

Now execute the stored procedure:

 Parameters:

@db_name: Database name that needs to be backup

@file_path: File path where backup needs to be stored.

 Note: File path format should be “:\…………\Backup\”

 Procedure execution:

USE MASTER;
GO
EXEC usp_Backup_Database 
			@db_name = N'Source',
			@file_path = N'C:\Bkptest\Source\';
GO

This is really helpful when we need to deal with disk space.

Just to demonstrate I have shown an example with one database that same can be loop for all user defined databases using a table variable and while loop.

 

Posted in SQL Server DBA | Tagged , , , , , , , | 1 Comment

How to Delete Duplicate Records in SQL Server

How to Delete Duplicate Records in Sql Server
How to Delete Duplicate Records in SQL Server

Usually on daily basis we usually need to perform removing duplicate records from a table. This post can help you to understand “How to Delete Duplicate Records in SQL Server”.

Here consider an example for removing duplicate records.

IF EXISTS(SELECT 1 FROM sys.sysobjects WHERE TYPE = 'U' AND NAME = 'Test')
BEGIN
	DROP TABLE Test; 
END;
GO
CREATE TABLE Test(id INT,name VARCHAR(100),age INT);
GO
INSERT INTO Test
VALUES (1,'A',34),
(1,'A',34),
(2,'B',37),
(3,'C',21),
(3,'C',21),
(3,'C',21);
GO
SELECT id,name,age FROM Test;

 

-- Now delete the duplicate records
WITH CTE(id,name,age,Duplicates)
AS
(
SELECT id,name,age,
ROW_NUMBER() OVER (PARTITION BY id, name, age ORDER BY id) AS Duplicates
FROM Test
)
DELETE FROM CTE
WHERE Duplicates > 1
GO

 

Now check the table to make sure duplicates are being removed from table.

Posted in SQL Development, SQL Scripts | Tagged , , , , , , , , | Leave a comment