The following T-SQL script will extract all data/log files for the currently attached databases, and then scan all of those directories to find files that are not being used by SQL Server. This will quickly locate mdf, ldf or ndf files located in your data and log directories to free up space.

SET NOCOUNT ON;
GO
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = 'func_SplitPath')
	DROP FUNCTION dbo.func_SplitPath
GO
IF object_id('tempdb..#tmp_sql_files') IS NOT NULL
BEGIN
   DROP TABLE #tmp_sql_files
END
GO
IF object_id('tempdb..#tmp_os_files') IS NOT NULL
BEGIN
   DROP TABLE #tmp_os_files
END
GO
CREATE FUNCTION dbo.func_SplitPath
(@filename varchar(2048), @part int)
RETURNS varchar(2048)
AS
BEGIN

	DECLARE @pos AS int
	
	SET @pos = CHARINDEX('\',REVERSE(@filename))

	IF (@pos > 0)
		BEGIN
			SET @pos = LEN(@filename) - @pos
			IF (@part = 1) -- Directory
				RETURN LEFT(@filename,@pos)
			ELSE
				RETURN RIGHT(@filename,LEN(@filename) - @pos - 1)
		END
	RETURN ''
END
GO

DECLARE cur_dbs CURSOR
READ_ONLY
FOR SELECT name FROM master.dbo.sysdatabases WHERE DATABASEPROPERTYEX(name,'Status') = 'ONLINE'

DECLARE @dbname sysname
OPEN cur_dbs

CREATE TABLE #tmp_sql_files (filename varchar(2048) NOT NULL, dir varchar(2048) NULL)

FETCH NEXT FROM cur_dbs INTO @dbname
WHILE (@@fetch_status <> -1)
BEGIN
	IF (@@fetch_status <> -2)
	BEGIN
		DECLARE @sql varchar(2048)

		SET @sql = 'SELECT RTRIM(filename),NULL FROM [' + @dbname + '].dbo.sysfiles'

		INSERT INTO #tmp_sql_files
		EXEC(@sql)
		
	END
	FETCH NEXT FROM cur_dbs INTO @dbname
END


CLOSE cur_dbs
DEALLOCATE cur_dbs

-- Split the files and directories portions up
UPDATE #tmp_sql_files
SET dir = dbo.func_SplitPath(filename,1)

UPDATE #tmp_sql_files
SET filename = dbo.func_SplitPath(filename,0)



--- Get files in these directories from the OS
DECLARE cur_files CURSOR
READ_ONLY
FOR SELECT DISTINCT dir FROM #tmp_sql_files

DECLARE @dir varchar(2048)
OPEN cur_files

CREATE TABLE #tmp_os_files (filename varchar(2048))

FETCH NEXT FROM cur_files INTO @dir
WHILE (@@fetch_status <> -1)
BEGIN
	IF (@@fetch_status <> -2)
	BEGIN
		DECLARE @cmd varchar(255)
		SET @cmd = 'dir /B ' + @dir
		
		INSERT INTO #tmp_os_files
		EXEC master..xp_cmdshell @cmd

		UPDATE #tmp_os_files
		SET filename = @dir + '\' + filename
		WHERE filename IS NOT NULL AND CHARINDEX('\',filename) = 0
	END
	FETCH NEXT FROM cur_files INTO @dir
END

CLOSE cur_files
DEALLOCATE cur_files

DELETE FROM #tmp_os_files
WHERE filename IS NULL

ALTER TABLE #tmp_os_files ADD dir varchar(2048) NULL;
GO
-- Split the files and directories portions up
UPDATE #tmp_os_files
SET dir = dbo.func_SplitPath(filename,1)

UPDATE #tmp_os_files
SET filename = dbo.func_SplitPath(filename,0)


-- files in data/log directories that are not being used by sql server
SELECT o.dir, o.filename
FROM #tmp_os_files o
	LEFT OUTER JOIN #tmp_sql_files s ON
		o.filename = s.filename
WHERE s.filename IS NULL
	AND (o.filename LIKE '%.mdf'
		OR o.filename LIKE '%.ldf'
		OR o.filename LIKE '%.ndf')


Create Private Network in VMware

Published 12/26/2007 by Andy in Windows

The follow is a short how to for creating a private network, for instance used as cross-over type connections amongst two virtual machines. This was doing using Windows version of VMware Server, with Fedora 8 as the guest OS.

 

Create a Private Network

Before you can add a new ethernet device to the guest images, we first need to create host only network. This is done using from the 'Host->Virtual Network Settings...' menu within the VMware server console.

From the 'Host Virtual Adapters' tab, click the 'Add..' button.

Add VMnet

At the Add Network Adapter dialog, choose one of the free VMNet names to add, in our case VMnet3 was open.

Finally, back at the Host Virtual Adapters tab, click 'Apply' before proceeding.

DHCP

Now move to the 'DHCP' tab, and select the 'VMnet3' network. Click 'Remove' since we don't need to provide DHCP service for this virtual network. Now choose Ok to get back to the VMware server console.

Adding Ethernet Device to Virtuals

With a new private virtual network created it is time to "plug in the cable" for our virtual machines, by performing the following. With the guest machine powered down, select 'Edit virtual machine settings', then click 'Add...' on the hardware tab.

New Ethernet

Select 'Ethernet Adapter' from the Hardware type list, then 'Next >'

Network Type

At the 'Network Type' dialog, change the connection to 'Custom', and select our 'VMnet3' option, making sure the 'Device status' is set to 'Connect at power on'.

Configure Our New Network

With the all the guest images powered, it is time configure the devices within Fedora. By default, Fedora will try to bring up the interface eth1 using DHCP. Since we have have DHCP disabled it will fail to acquire an address (at take a bit for startup to complete). Once you are logged into a console, we need to configure our static addresses for each virtual.

First, confirm the new network adapter is there, by running ifconfig eth1:

#ifconfig eth1
eth1 Link encap:Ethernet HWaddr 00:0C:29:2C:AF:B6
inet6 addr: fe80::20c:29ff:fe2c:afb6/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:991 errors:0 dropped:0 overruns:0 frame:0
TX packets:39 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:240702 (235.0 KiB) TX bytes:2654 (2.5 KiB)
Interrupt:18 Base address:1480

Your output should be similar. Make note that there is no 'inet addr' line, since we don't have the eth1 device setup as static. To do so, edit /etc/sysconfig/network-scripts/ifcfg-eth1 to look like the following:

# Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE]
DEVICE=eth1
BOOTPROTO=static
IPADDR=10.0.0.11
ONBOOT=yes
HWADDR=00:0C:29:2C:AF:B6
TYPE=Ethernet

Notice the IPADDR line...this will be the static IP address used for the private network. For each virtual machine you want to put on this network, configure it the same as above, editing the ifcfg-eth1 file, but change the IPADDR to be their unique IP address on the 10.0.0 non-routed network.

Our last step is to remove the restrictive default firewall rules of iptables applies. Since this network will be private among only the hosts we want, we can accept all traffic on this interface by editing /etc/sysconfig/iptables adding the following line:

-A RH-Firewall-1-INPUT -i eth1 -j ACCEPT

Making sure it is somewhere above the last REJECT lines near the bottom.  To further restrict access down to the port level, you would have to add the following rules to the iptables file:

-A RH-Firewall-1-INPUT -s SOURCE_IP_ADDRESS -p tcp --dport 8000 -j ACCEPT

Where SOURCE_IP_ADDRESS is the source IP address allowing in port 8000 tcp connections.

 


DRBD acts as a virtual layer between the OS file system and the raw disk device (or can actually work against LVM devices). Hence the reason for having a kernel module. To setup a second raw disk device on our VMware images, you can perform the following steps, with the guest powered off.

Add New Virtual Disk 

At the VMware server console window with your guest selected in inventory, click 'Edit virtual machine settings'. On the 'Hardware' tab, select 'Add...', choosing 'Hard Disk', and then 'Create a new virtual disk', keeping 'SCSI' as the type, and finally set your desired size and uncheck the 'Allocate All Disk Space Now' option if you so desire.

With the new disk added in VMware, it is now time to partition it within Fedora 8. After the guest has started, you have several programs you can use to do the partioning. I find cfdisk the easiest.

Partitioning with cfdisk

By default your new disk device will appear as /dev/sdb. Fire up cfdisk for that new disk with:

cfdisk /dev/sdb

cfdisk

Your console should look like above, showing no other partitions. From within cfdisk, use the arrow keys and to select 'New', the choose 'Primary' at the type, accept the default size (which should be the entire disk), and then finally, make sure you select 'Write' so the partion changes get written to the disk. Our new partion will be a device named /dev/sbd1.

At this stage the disk partion could be formatted with a new file system. In our case, we will be directing DRBD to manage this raw partition when we complete the compile and configure DRBD.


Ever wonder when the last time your table stats where updated (perhaps done automatically because auto_stats is on?). Here is your answer:

SELECT i.name AS [Index Name], STATS_DATE(i.id, i.indid) AS [Statistics Date]
FROM sysobjects o, sysindexes i
WHERE o.name = 'table_name' AND o.id = i.id


MySQL Backup VBScript

Published 9/20/2007 by Andy in MySQL | VBScript | Windows

The following VBScript will backup all MySQL databases on the localhost to a directory and maintain 10 days worth of backups

'* Copyright (C) 2007 Andrew Loree
'****************************************************************************
'* mysqlbackup.vbs - Backup all mysql databases to a daily backup file
'*	doing a rotation, limiting maximum number of backups retained
'****************************************************************************
'*  This program is free software; you can redistribute it and/or
'*  modify it under the terms of the GNU General Public License
'*  as published by the Free Software Foundation; either version 2
'*  of the License, or (at your option) any later version.
'*
'*  This program is distributed in the hope that it will be useful,
'*  but WITHOUT ANY WARRANTY; without even the implied warranty of
'*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'*  GNU General Public License for more details.
'*
'*  You should have received a copy of the GNU General Public License
'*  along with this program; if not, write to the Free Software
'*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
'****************************************************************************
'* Version History:
'*	1.0 - Initial Release
'****************************************************************************
Option Explicit
Dim backup_dir, num_days, user, password, arguments, backup_file
Dim oShell, oFS, oDrive, nResults

	backup_dir = "C:\some\path\here\"
	num_days = 10
	user = "XXXXXX"
	password = "YYYYYYY"

	backup_file = backup_dir & Year(Date) & PadZero(Month(Date)) & PadZero(Day(Date)) & "_all_databases.bak"
	arguments = "--user=" & user & " --password=" & password & " --all-databases --quick --result-file=" & backup_file

	Set oShell = CreateObject("WScript.Shell")

	WScript.Echo("Creating backup file " & backup_file)
	nResults = oShell.Run("mysqldump.exe " & arguments, 1, TRUE)

	Set oShell = Nothing


	
	Dim folder, files, file, regex, Matches, Match, counter, backups, i, cur

	Set oFS = CreateObject("Scripting.FileSystemObject")
	Set regex = New regexp
	regex.Pattern = "[0-9]{8}_all_databases\.bak"
	regex.Global = True
	regex.IgnoreCase = True
	
	Set folder = oFS.GetFolder(backup_dir)
	Set files = folder.Files

	counter = 0

	ReDim backups(0)

	For Each file In files
		Set Matches = regex.Execute(file.Name)
		For Each Match in Matches
			Redim Preserve backups(counter)
			backups(counter) = Match.Value
			counter = counter + 1
		Next
	Next

	cur = 0
	For i = counter - 1 To 0 Step -1
		If (cur >= num_days) Then
			WScript.Echo("Deleting " & backups(i))
			oFS.DeleteFile(backup_dir & backups(i))
		Else
			WScript.Echo("Keeping " & backups(i))
		End If
		cur = cur + 1
	Next


	Set oFS = Nothing



' PadZero - adds preceding zero to values less than 10
Function PadZero(val)

	If (val < 10) Then
		PadZero = "0" & val
	Else
		PadZero = val
	End If
End Function


The following VBScript will retrieve the current hotfix for a specified SQL 2005 Server, and return that hotfix as a the return code. Useful in batch files for selectively applying unattended service packs.

Option Explicit
Dim sServer, sInstance, nVersion, bVerbose, sSQLServer

If (ParseCommandLine()) Then
	nVersion = GetSQLServerHotfix(sServer, sInstance)
	WScript.Quit(nVersion)
Else
	ShowUsage()
	WScript.Quit(-1)
End If


'*******************************************************************
'* GetSQLServerHotfix - Retrieves SQL 2005 server hotfix version #
'*******************************************************************
Function GetSQLServerHotfix(strServer, strInstance)
Dim oWMI, oRst, oRow, nHotfix, sSQLName, sVersion, sTemp, nPos

	nHotfix = 0

	If (UCase(sInstance) <> "MSSQLSERVER") Then
		sSQLName = "MSSQL$" & sInstance
	Else
		sSQLName = "MSSQLSERVER"
	End If

	Set oWMI = GetObject("winmgmts:\\" & strServer & "\root\Microsoft\SqlServer\ComputerManagement")
	Set oRst = oWMI.ExecQuery("SELECT PropertyStrValue FROM SQLServiceAdvancedProperty " _
					& " WHERE PropertyName='Version'" _
					& " AND ServiceName='" & sSQLName & "'",,48)

	For Each oRow in oRst
		sVersion = oRow.PropertyStrValue
		If (bVerbose) Then
			WScript.Echo("Server: " & sSQLServer)
			WScript.Echo("Version: " & sVersion)
		End If
		If (Len(sVersion) > 2) Then
			sTemp = sVersion
			nPos = InStr(3,sTemp,".")
			If (nPos > 0) Then
				sTemp = Mid(sTemp,nPos + 1)
				nPos = InStr(1,sTemp,".")
				If (nPos > 0) Then
					nHotfix = Left(sTemp,nPos-1)
					If (bVerbose) Then
						WScript.Echo("Hotfix: " & nHotfix)
					End If
				End If
			End If
		End If
	Next

	Set oRst = Nothing
	Set oWMI = Nothing

	GetSQLServerHotfix = nHotfix

End Function



'*******************************************************************
'* ParseCommandLine - Parses command line options into global vars
'*******************************************************************
Function ParseCommandLine()
Dim objArgs, i, sNextArg

	
	Set objArgs = WScript.Arguments
	For i = 0 To objArgs.Count - 1
		If (i < objArgs.Count - 1) Then
			sNextArg = objArgs(i+1)
		Else
			sNextArg = ""
		End If
		Select Case (UCase(objArgs(i)))
			Case "/SERVER":
				sSQLServer = sNextArg
				i = i + 1
			Case "/VERBOSE":
				bVerbose = True
			Case "/HELP":
				ParseCommandLine = False
				Exit Function
			Case "/H":
				ParseCommandLine = False
				Exit Function
		End Select
	Next

	' Check for valid arguments
	If (Len(sSQLServer) > 0) Then
		' Parse the server name/instance
		Dim nSlash
		nSlash = InStr(1,sSQLServer,"\")
		If (nSlash > 0) Then
			sInstance = Mid(sSQLServer,nSlash+1)
			sServer = Left(sSQLServer,nSlash-1)
		Else
			sInstance = "MSSQLSERVER"
			sServer = sSQLServer
		End If
		ParseCommandLine = True
	Else
		ParseCommandLine = False
	End If

End Function