Found a problem with Windows Server Backup in server 2008 where it would start then give an access denied error.
This was an exchange server and I had changed the data disk for a new one. Somehow this had mucked up the security rights on the second data disk (used for backup).
I got WSB to create a brand new backup, which formatted the second disk, and it was happy. Take care! Don't format your exchange data disk for backup!!!
Saturday, 26 December 2009
Sunday, 20 December 2009
IBM DS4700 - Channel B Fault
Our fibre-channel SAN (IBM DS4700) is not working on channel B, despite the diagnostics showing OK. The VMware servers can't see anything on the B path - they are showing it as dead.
This may be the cause of some of the server corruption we've had lately - presumably the B channel has been going up and down and has now finally given up the ghost.
All servers are now running happily on A on that SAN and a call to IBM will be logged when we restart after Christmas.
This may be the cause of some of the server corruption we've had lately - presumably the B channel has been going up and down and has now finally given up the ghost.
All servers are now running happily on A on that SAN and a call to IBM will be logged when we restart after Christmas.
Tuesday, 15 December 2009
ESXpress Backup - Target Groups
I created a extra de-duplication target for ESxpress yesterday thinking that the system would balance the load between the two. In fact, it doesn't do this at all. It simply uses it as an overflow when the first target is full, or if it becomes unavailable.
Instead I have now targetted the first two ESX servers to one de-dup unit and the second two to the other, thus spreading the load manually.
If you're thinking of getting a backup solution for ESX, this seems as good as any, by the way. The restore is quick, easy and reliable and in normal service you can just leave it to get on with the backups every night, without interference. It doesn't have some of the advanced config options of a more fancy solution, but it's great if you just want something to backup reliably, and always restore OK.
Incidentally, don't shut the DeDup appliance down with a power off command from ESX - always do a proper linux shutdown or the appliance will want to scan the backup disk at next bootup - this took SIX HOURS this weekend for a full 2TB disk.
Instead I have now targetted the first two ESX servers to one de-dup unit and the second two to the other, thus spreading the load manually.
If you're thinking of getting a backup solution for ESX, this seems as good as any, by the way. The restore is quick, easy and reliable and in normal service you can just leave it to get on with the backups every night, without interference. It doesn't have some of the advanced config options of a more fancy solution, but it's great if you just want something to backup reliably, and always restore OK.
Incidentally, don't shut the DeDup appliance down with a power off command from ESX - always do a proper linux shutdown or the appliance will want to scan the backup disk at next bootup - this took SIX HOURS this weekend for a full 2TB disk.
Sunday, 13 December 2009
Exchange 2007 - SA fails to start
The SA would not start on an exchange 2007 server, leaving no mail delivery and no web access.
This particular server had been removed from AD and readded. You need to go into ADUC and add the computer to both exchange groups in USERS and both exchange groups in the system create EXCHANGE OU.
Then after a reboot it comes up fine.
Useful if you have an AD replica on exchange and you have to restore from a snapshot, rendering the AD replica useless and needing a dcpromo /forceremoval followed by a rejoin of the domain and a dcpromo.
This particular server had been removed from AD and readded. You need to go into ADUC and add the computer to both exchange groups in USERS and both exchange groups in the system create EXCHANGE OU.
Then after a reboot it comes up fine.
Useful if you have an AD replica on exchange and you have to restore from a snapshot, rendering the AD replica useless and needing a dcpromo /forceremoval followed by a rejoin of the domain and a dcpromo.
The RPC Server is Unavailable
This error stopped a server becoming a domain controller tonight. The problem was with the network card - I tried to ping the domain name and got a weird address. The DNS order was screwed up. In the end I had to delete and re-create the network card.
Wednesday, 9 December 2009
Using DotNet to Copy / Sync SQL databases
I'm creating a new system for the till in the refectory and as part of this there's going to be a locally stored database as well as one on the main database server. The idea is that the till can run disconnected from the network, but when it sees the network again it will resync the database.
It works like this:
The master database for kitchen product, users and product groups is on the network so that a back end application can edit them.
The master database for transactions is on the till.
Every x minutes the till synchronises the databases if possible. In order to do this I could either use SQL to connect the two (which proved difficult given that there could be more than one till) or use DotNet. I chose the latter.
In order to ensure that rows are copied including their key, you need the Set Identity_Insert command alongside an Insert Into command. To build these commands up automatically on rows that have to be synched, first the old row is deleted (if it exists) and then I use the following code to build the insert into command: (the strings "cols" and "vals" are the return from ColumnList and ColumnValues and it's nice and generic so will work with any dataset.
Shared Function BuildInsertQuery(ByVal TableName As String, ByVal Vals as string, ByVal Cols As String) As String
Dim Query As String = IION(TableName)
Query += "Insert into " + TableName + " (" + Cols + ") values (" + Vals + ")"
Return Query
End Function
Shared Function IION(ByVal TableName As String) As String
Return "Set Identity_Insert " + TableName + " ON" + Chr(13) + Chr(10)
End Function
Shared Function IIOFF(ByVal TableName As String) As String
Return Chr(13) + Chr(10) + "Set Identity_Insert " + TableName + " OFF"
End Function
Shared Function ColumnList(ByVal DT As DataTable) As String
' returns a list of columns in the datatable
Dim List As String = ""
For Each Col As DataColumn In DT.Columns
If List <> "" Then
List += ","
End If
List += Col.ColumnName
Next
Return List
End Function
Shared Function ColumnValues(ByVal Row As DataRow) As String
Dim Val As String = ""
For foo As Integer = 0 To Row.ItemArray.Length - 1
If foo > 0 Then
Val += ","
End If
If Row.Item(foo).GetType.ToString = "System.DateTime" Then
Dim Dt As Date = Row.Item(foo).ToString
Val += "'" + ims.UtilitiesNonSQL.ConvertDateForSQL(Dt) + "'"
Else
Val += "'" + Row.Item(foo).ToString.Replace("'", "") + "'"
End If
Next
Return Val
End Function
Seems to work!
It works like this:
The master database for kitchen product, users and product groups is on the network so that a back end application can edit them.
The master database for transactions is on the till.
Every x minutes the till synchronises the databases if possible. In order to do this I could either use SQL to connect the two (which proved difficult given that there could be more than one till) or use DotNet. I chose the latter.
In order to ensure that rows are copied including their key, you need the Set Identity_Insert command alongside an Insert Into command. To build these commands up automatically on rows that have to be synched, first the old row is deleted (if it exists) and then I use the following code to build the insert into command: (the strings "cols" and "vals" are the return from ColumnList and ColumnValues and it's nice and generic so will work with any dataset.
Shared Function BuildInsertQuery(ByVal TableName As String, ByVal Vals as string, ByVal Cols As String) As String
Dim Query As String = IION(TableName)
Query += "Insert into " + TableName + " (" + Cols + ") values (" + Vals + ")"
Return Query
End Function
Shared Function IION(ByVal TableName As String) As String
Return "Set Identity_Insert " + TableName + " ON" + Chr(13) + Chr(10)
End Function
Shared Function IIOFF(ByVal TableName As String) As String
Return Chr(13) + Chr(10) + "Set Identity_Insert " + TableName + " OFF"
End Function
Shared Function ColumnList(ByVal DT As DataTable) As String
' returns a list of columns in the datatable
Dim List As String = ""
For Each Col As DataColumn In DT.Columns
If List <> "" Then
List += ","
End If
List += Col.ColumnName
Next
Return List
End Function
Shared Function ColumnValues(ByVal Row As DataRow) As String
Dim Val As String = ""
For foo As Integer = 0 To Row.ItemArray.Length - 1
If foo > 0 Then
Val += ","
End If
If Row.Item(foo).GetType.ToString = "System.DateTime" Then
Dim Dt As Date = Row.Item(foo).ToString
Val += "'" + ims.UtilitiesNonSQL.ConvertDateForSQL(Dt) + "'"
Else
Val += "'" + Row.Item(foo).ToString.Replace("'", "") + "'"
End If
Next
Return Val
End Function
Seems to work!
Friday, 4 December 2009
SQL 2008 - Error Saving Schema Changes
When saving changes to the design of tables in SQL 2008, if it's anything more than an extra column at the end, we get the error:
Saving changes is not permitted. The changes you have made require the following tables to be dropped and re-created
To fix this, one needs to go to Tools, Options, Designer, Table and Database Designer and untick the following:

This would appear to be a changed default from SQL 2005 (MS - please stop doing this - it drives up nuts!)
Nick.
Saving changes is not permitted. The changes you have made require the following tables to be dropped and re-created
To fix this, one needs to go to Tools, Options, Designer, Table and Database Designer and untick the following:

This would appear to be a changed default from SQL 2005 (MS - please stop doing this - it drives up nuts!)
Nick.
Thursday, 3 December 2009
VB DotNet - Please Wait window
We have need of a "Please Wait" type window in our code that comes up and displays only for as long as a particular chunk of code is running. Then it terminates.
I've done this by creating a form with the required "please wait" text and a nice animated logo which I load up in a new thread when I want it to show. It will thus display even though the code is busy doing something else.
Don't forget to thread.abort when it's finished to clear the form, or keep a global variable somewhere that the thread looks at to know when to stop itself. Alternatively, if you're feeling really brave you could use inter-thread communications, although it seems OTT for something as simple as this. Also, you'll probably want to set the form to "Topmost" so it's always on top.
Interestingly, threads seem to be a good way of opening up new forms when old forms are still open and you want them both to be functional even if the other one is busy. For example:
Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click
Dim EBT As New Threading.Thread(AddressOf ExistingBookingsThread)
EBT.Start()
End Sub
Private Sub ExistingBookingsThread()
Dim EB As New ExistingBookings
EB.ShowDialog()
End Sub
This code snippet handles a button press for a new form by starting a new thread which calls "ExistingBookingsThread" which is a holding subroutine that displays the form then terminates when the form is closed.
Nick
I've done this by creating a form with the required "please wait" text and a nice animated logo which I load up in a new thread when I want it to show. It will thus display even though the code is busy doing something else.
Don't forget to thread.abort when it's finished to clear the form, or keep a global variable somewhere that the thread looks at to know when to stop itself. Alternatively, if you're feeling really brave you could use inter-thread communications, although it seems OTT for something as simple as this. Also, you'll probably want to set the form to "Topmost" so it's always on top.
Interestingly, threads seem to be a good way of opening up new forms when old forms are still open and you want them both to be functional even if the other one is busy. For example:
Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click
Dim EBT As New Threading.Thread(AddressOf ExistingBookingsThread)
EBT.Start()
End Sub
Private Sub ExistingBookingsThread()
Dim EB As New ExistingBookings
EB.ShowDialog()
End Sub
This code snippet handles a button press for a new form by starting a new thread which calls "ExistingBookingsThread" which is a holding subroutine that displays the form then terminates when the form is closed.
Nick
Subscribe to:
Posts (Atom)