Monday, April 16, 2007

 

IIS 6.0 and other hidden options

I had thought that I had found the internet nirvana.

And it was in the form of:

ASPExecuteinMTA

This little gem reports to have all sorts of benefits for turning on. Statements like:

Your system will run significantly faster, and amazing technical descriptions like that.

However, what they don't tell you is when you run in this mode, you also loose the ability to login as credentialled users. You can still login, mind you, but any scripting you use will default to IIS's IWAM_USR account - which generally is given limited to no permissions other than reading the directory of the website you are hosting.

This is a good thing - because if you give the IWAM_USR account permissions to, um, let's say, write, or perhaps Full control -all sorts of security bad things can happen.

Like for instance being swarmed over by lovely, furry, fuzzy script kiddies and the like.

However, when you turn on the MTA switch, you will find that the FSO (or file scripting object) no longer functions because even if you login as "administrator" on the page that previously worked, it will now cause FSO to have security permissions of, IWAM_USR. And all sorts of things will happen.

Like for instance - "Directory does not exist" or "File not Found" - even when obviously the directories do exist, and the files are there.

I love microsoft....

Friday, April 06, 2007

 

Speaking of SQL

I have run into a situation where I am not sure if my SQL server is operating normally, or if it's madly running out of control and into oblivion (which is a great, fun game btw).

I manage and design a website www.toolup.com.

On this site, I use SQL extensively. And the ASP pages that I write use connections and recordsets quite a bit. When I go to look at all the processes running on the server I find hundreds of sleeping connections. Is this a result of connection pooling by the system. Is it a result of connection pooling by the IIS web gardens, of which I have probably 64+64 + 32 for a total of 160 actual web processes running the website.

The website seems to respond very quickly. On the order of 1/2 second or so. Often times returning in a 1/10th of a second. So performance is not an issue.

I have run through the code and made sure that I have closed my connections.

However, doesn't the connection get automatically closed upon the closure of a script? Is running conn.close() redundant?

does conn.close() happen when you execute

set conn = nothing?

So while I contemplate this fine feature of SQL - I find that I am staring at roughly 647 pids, most of which are happily sleeping, and my server's CPU load is fairly low all of the time, with occasional spikes to the disk or CPU load.

I just can't help but think that all of these pids should be going away after they complete.

Thursday, January 04, 2007

 

Dumb Ass Error Messages

I love Microsoft error messages. I really do. Especially since I charge by the hour.

I was setting up a SQL "Maintenance Plan" to do regular backups and stuff. I've done it many times before, and it always worked pretty smoothly. After setting them up, I go through and manually run the Agent jobs to make sure they all work. They always have before, but as I said, I charge by the hour, so I go ahead and check them out. They all work except the transaction log backup step! Microsoft gives me the incredibly terse and ultimately meaningless error message shown here:

Executed as user: CPAF\sqlserver. sqlmaint.exe failed. [SQLSTATE 42000] (Error 22029). The step failed.

Now, this is simply not a lot to go on, so I examine the system logs and such and come upon the following:

SQL Server Scheduled Job 'Transaction Log Backup Job for DB Maintenance Plan 'Games Database Maintenance'' (0x8B21AC552BA46346ABCA7FD26F22B684) - Status: Failed - Invoked on: 2007-01-04 15:35:54 - Message: The job failed. The Job was invoked by User CPAF\administrator. The last step to run was step 1 (Step 1).

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.


This message is verbose and just as meaningless as the last. This has a very high words-to-information ratio. I wonder what the units are for this? We know that information is measured in bits, so the ratio is words per bit (words/bits). A message like the one above has many words and virtually no information -- a very high words/bit ratio. I propose we call this unit the "verbit". Therefore, we could say that this message has millions, perhaps trillions of verbits. Verbits are roughly equivalent to the "bullshit factor". But I digress...

At this point it will clarify things later if I explain I had just recently added a 2nd hard drive to offload the backups onto. When troubleshooting, one of the things you always look for is what changed. Chances are, the new thing is somehow involved in the problem. Factor the new hard drive in with the fact that most backup problems I have had in the past are simply security related (that's why you can't "open the backup device" when you try to backup databases to your Desktop -- unless you are running SQL Server as local system or administrator) and you'll understand why I quickly had myself convinced that the problem was related to the security settings of the new hard drive.

After spending several hours meticulously examining security settings, permissions, verifying accounts, inheritance, etc, it finally dawned on me that the problem had nothing to do with permissions. I was running a maintenance plan on a database that happened to be running in simple recovery mode! There is no option to backup a transaction log for simply recovery databases. An error message that at the indicated "One or more databases are using the simple recovery model" would have saved hours of red-herring work.

Thanks Microsoft! I'm going skiing this weekend because of the extra hours you cost me, er, my client! Oh, and in case you are wondering, this post has at least several million verbits. I like to think it is because of the embedded Microsoft error messages.






Wednesday, November 15, 2006

 

Replication and Relationships

This was one I struggled with for a long time. I was attempting to publish a SQL Server 2000 database, using merge replication. Everything seemed to work fine. I set up the publisher and distributor as per the books. I Published the database. I had to add GUID's and spent some time removing identity columns (demoting them to just INTs) wherever I could in the database. I learned a lot about identity range management. When all was said and done, I then subscribed to the database. The subscription went smoothly. I tested, and replication seemed to be working. Wow, I thought. Just like in the books. Soon thereafter, I discovered how horribly wrong I was.

Since the testing phase is that part of the development cycle where errors are guaranteed to fail to appear, my database replicated flawlessly. So, after a few weeks of testing, it went into production. Production is the phase after development where errors occur. I suddenly started receiving replication errors. The typical error was:
  • Msg 548, Level 16, State 2, Server %s, Line 1 The identity range managed by replication is full and must be updated by a replication agent. The INSERT conflict occurred in database '%s', table '%s', column '%s'. Sp_adjustpublisheridentityrange can be called to get a new identity range. The statement has been terminated.
This is where I learned about Identity range management. Basically, when replicating identity values, each subscriber (and the publisher) is given their own range of identity values to use. When a subscriber gets about 80% of the way through its' range, it will communicate with the publisher and get a new range. So I republished with outrageous ranges for the identity values. I continued to get the same error. I ran DBCC CHECKIDENT('table', NORESEED) to see what the current values were. They were well within the 80%. I went ahead and reseeded anyway (DBCC CHECKIDENT('table', RESEED)) and promptly continued to receive error messages. I wailed. I cried. I gnashed my teeth. Despite all evidence to the contrary, SQL Server would continue to insist that my identity range was full.

Since it was completely clear that the identity range was not, in fact, full, it seemed to me that I must somehow be misunderstanding the message. Unfortunately, no matter how I examined the message it seemed to keep saying that the identity range was full. It mocked me. I noticed that the errors always seemed to occur in tables with foreign key dependencies. It began to dawn on me with glacial slowness that the error had nothing at all to do with identity ranges. In fact, it had nothing to do with identity values at all. Of Course! The error message seems so obvious now! Thank you Microsoft, for your clear and informative error messages! The error message had even gone so far as to include a solution that would not fix the problem.

What was happening was that, during replication, data would start getting pumped into ancillary tables (you know, the kind that hold phone numbers), but sometimes (not always) the agent would try to pump the data into the ancillary table before a matching entry in the primary table was present. This generated a relational error, and prevented the data from getting propagated across. By the time I went to the conflict viewer to resolve the conflicts, the primary table was populated, so I could accept the data and it would then propagate fine.

Once I realized that the true error was due to referential integrity, I began examining the relationships themselves. And I looked once more at the property called "Not for replication". The palm of my hand exploded upon my forehead! All the devices of Bill Gate's minions were now laid bare before me, and I realized my folly. I had looked at that option before, when I was first preparing the database for replication. And my first interpretation of that option was that by checking it, the relationship would not be enforced at the subscriber. Well, of course I wanted it enforced at the subscriber, so I left in unchecked. What the option really means, though, is that the relationship is not to be enforced during the replication process. The same meaning as the "not for replication" option for Identity values.

By declaring relationships as "not for replication", the problem was solved. I feel like an idiot. I mean, in retrospect, the error message is perfectly clear. At the risk of appearing exceedingly stupid, I have to ask: Why would you ever want a relationship enforced during replication? As the rules were enforced already during the initial data entry, you know that parent records have to exist. So why isn't "not for replication" the default setting? Why is it an option at all? Anyone?



 

Mission Statement

I cannot tell you the number of times I have struggled with some obscure (or obvious) problem, that no web site or book addressed. It often times seems as if no one else in the world ever has problems. The books often read like a reprint of the online help -- "click here, set this option to 'foo' and you're done!" Yet no matter how many times I compare what the book says to what I have done, it simply refuses to work. SQL Server will typically cough up verbose error messages that may or may not have any relation to reality. My biggest complaint about books is they never seem to be talking about my specific case. I think this means that I am doing everything wrong, and so thus the title of the blog.

So, when I struggle with such an issue, and I cannot find any obvious solutions in the books or online, I will post it here, along with the resulting solution (if any). The fact that the problem may be caused, in large part, by my bone headed approach is irrelevant. I work in a school district. I know I am not the only bonehead out there. Please feel free to submit any similar stories you have. Accepting your stupidity is only the first step. Letting everyone know just how stupid you are in a public forum is the next. This is why God made blogs.

This page is powered by Blogger. Isn't yours?