SQL Server system table map
After trying to modify unique index names on tables in a database using the INFORMATION_SCHEMA
views and getting nowhere fast, I delved into the system tables to see if they would shed any light on how to do it. This was even more confusing as it’s not obvious how these tables fit together. If only there was a map of the relationships between the system tables. Well, there is - Microsoft helpfully supply one on their SQL Server website. Very useful.
Visual Studio 2005 and proxy authentication
Using Visual Studio 2005 today, I received a “407 Proxy Authentication Required” message when trying to search the online help integrated into the IDE. KB910804 from Microsoft held the answer.
In order to allow VS2005 through an authenticating proxy, you have to edit the Visual Studio configuration file located at C:\Program Files\Common Files\Microsoft Shared\Help 8\dexplore.exe.config
. To add support for the proxy, make sure the proxy element is present:
where the correct proxy server is configured in the proxyaddress element.
If you use the integrated help viewer, you must also add this xml to the configuration file located at C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.exe.config
.
Fusion log viewer
Whilst trying to work out why some code was running very slowly (see System.Diagnostics.Process and speed), I tried to see whether the slowness was caused by loading code contained in a separate dll. To get this information, I needed to look at the fusion logs. Configuring these logs is not fool-proof, so having spent a few hours getting it working, I thought I’d document the process.
Suzanne Cook’s blog was quite useful, as was the Assembly Binding Log Viewer article on MSDN, but neither of them contained exactly what was needed.
To set up the fusion logs ready for viewing, some entries need to be added to the registry in the HKEY_LOCAL_MACHINE\Software\Microsoft\Fusion
key. The combination needed depends on what you’re trying to inspect. The keys are:
-
LogFailures = 1 (DWORD Value)
This turns on failure logging so that failed attempts to locate all assemblies are logged. -
LogResourceBinds = 1 (DWORD Value)
This turns on failure logging so that failed attempts to locate satellite assemblies are logged. This is not logged by default. -
ForceLog = 1 (DWORD Value)
This turns on logging for all assembly binds - both failures and successes. By default, only failures are logged. This is useful if you want to verify that an assembly is loading from a specific directory instead of from the global assembly cache. -
LogPath = “C:\fusionlogs" (String Value)
If you want to view the fusion logs easily, set the LogPath to a directory to output them to. By default the log files go into the Temporary Internet Files folder of the current user’s profile. For an ASP.Net or a .Net Windows service application, the only way to view the fusion log is to use this option. This is because they run as users other than the current user. The directory specified must already exist and have appropriate file permissions to be written to. For ASP.Net applications, the ASPNET user must have write permission to the directory. If the permissions are wrong, there will be no log output.
Once you have configured the relevant logging options, running the .Net application will generation the fusion logs. Once generated, the logs can be viewed using the fuslogvw.exe
tool that comes as part of the framework SDK (mine was inside the SDK folder inside Visual Studio’s installation folder). I found that either the 1.1 or 2.0 version will work, but the 2.0 version is a little better as it has a few more options in the GUI:
To view a specific log, choose it from the main section and click the view log button. The log will open in an internet browser showing the assembly binding details.
System.Diagnostics.Process and speed
I was working on some code that seemed to take an age to get going. Simple I thought: run it throught the Red Gate ANTS Profiler, look at the offending code and sort the problem. I wish it was as straightforward. Profiling or debugging the code seemed to make it run quickly, so I had to resort to the good old technique of logging debug output line by line.
After finding the lethargic code, the line that stalled progress for almost a minute didn’t look that concerning:
A bit of Googling turned up trumps. A post by Brian Grunkemeyer from the BCL team gave the answer:
The way the Process class currently works, the first time you try to do anything that requires knowing the state of the current process, we take a snapshot of all the processes in the system. So yes, this operation is slow the first time you call it. We could potentially limit this snapshot to just the current process by requesting MORE information about the current process from Windows (CreateToolhelp32Snapshot is a peculiar method), but that leads into peculiar situations where the snapshot information for the current process then gets out of sync if you call another method on the Process class to enumerate all the other processes.
This initial snapshot must have been the cause of the delay. A quick code-edit later to avoid the use of the Process class (I was actually interested in the name of the executing file so I used Assembly.GetExecutingAssembly()
) and the almost 60 second pause was gone.
So why was it running quicker when debugging/profiling? I presume that the debugger/profiler would have been using the System.Diagnostics
namespace, and more specifically the Process
class, as part of its internals, thus the costly first call snapshot had already happened.
DNS error when adding a computer to a domain
After having several problems with my laptop accessing files on my server (the domain controller for my domain), I had a look in the event log and found this error:
The computer [computername] tried to connect to the server \\[servername] using the trust relationship established by the [domainname] domain. However, the computer lost the correct security identifier (SID) when the domain was reconfigured. Reestablish the trust relationship.
I figured that this may be the cause of the problems and so set about reestablishing the trust relationship between the laptop and the server. Sounded like a simple task, but the only (easy) way I could find to do this was to remove the laptop from the domain and then add it again. After removing it successfully, I kept getting an error when trying to re-add it:
The domain name [domainname] might be a NetBIOS domain name. If this is the case, verify that the domain name is properly registered with WINS. If you are certain that the name is not a NetBIOS domain name, then the following information can help you troubleshoot your DNS configuration. An error occurred when DNS was queried for the service location (SRV) resource record used to locate a domain controller for domain [domainname]. The error was: "No DNS servers configured for local system." (error code 0×0000267C DNS_ERROR_NO_DNS_SERVERS) The query was for the SRV record for _ldap._tcp.dc._msdcs.[domain]”
After puzzling for ages as to why it wasn’t happy, I checked my IP settings and found the problem. Somehow, the IP settings had changed to a specified IP address instead of using DHCP. Changing them back solved the problem straight away.