DB2 Net Search Extender's index update sheduling
The DB2 NSE service crashed my
DB2 server over the weekend... again!! And this time it corrupted one of
my user tablespaces!!! Very annoying. However, in the process of restoring the destroyed database from the most recent
backup, I noticed entries in the db2diag.log
file indicated that db2text
(the NSE indexing process) was trying to
update indexes for a database that no longer exists - ie a database that I dropped some time ago.
Now, this was not new to me... I'd actually seen this benign error before, but had not found a solution to it yet. You see, to fix the problem, the most obvious thing to do is simply drop the indexes via:
db2text 'DROP INDEX idx FOR TEXT CONNECT TO db USER name USING pass'
But, of course, the you cannot execute that, nor any other db2text
command, for a non-existent database!! An odd
scenario - I know. It's one that arises when you drop a database, whilst forgetting to first drop the associated NSE
indexes (something you would think the database would know how to take care of - just as it does for normal (non-NSE)
indexes). Anyway, in the past I'd performed some quick searches of the various NSE-related tables, but to no avail.
So that's as far as I had gone previously.
But this time, while I was waiting for DB2 to recover from backup, I decided to look into it a bit further. So, after a
short bit of googling, I came across
this page
on the IBM support site. It turns out that db2text
manages (or should I say mismanages) a scheduling file call
ctedem.dat
. This is a plaintext file that, so far as I can tell, is identical in format to a standard
crontab file, except for the obvious codes stored in comment lines. Here's a
link to a copy of my original ctedem.dat
file if you're interested.
So sure enough, the ctedem.dat
file contained a number of (well, two) references to the non-existent database (the
database in question was called JBH
). So removing those entries was simple, and did the trick quite nicely.
However, you know with DB2 NSE, nothing is ever that simple ;) While I was looking at the ctedem.dat
file, I soon
realised, that there were too many entries for my remaining NSE indexes... indeed, a couple of the NSE indexes were
listed twice! Now, this might not seem like such a big deal, except that it means that often db2text
will try to
update the same index twice simultaneously... and given that concurrent db2text
processes seems to be what kills my
DB2 server, this is something well worth fixing!
Now, as part of my software development process, I have some convenient scripts that drop / create / recreate all of my
project's NSE indexes. So, I went ahead an dropped all such indexes. And, to no surprise of mine, I found that several
now-defunct ctedem.dat
entries remained. So, I dutifully removed them (in fact, emptied the file completely), and
then created the necessary indexes, after which the ctedem.dat
file contained the exact expected entries - that is,
with no duplicates.
I then went a checked another DB2 instance on a different server, and found that it had similar old defunct ctedem.dat
entries too.
So, it seems that db2text
is indeed quite poor at managing its own ctedem.dat
scheduling file - indeed, doing things
like dropping / recreating databases is guaranteed to cause DB2 NSE's ctedem.dat
file to contain erroneous entries.
So, it is my strong suggestion, that anytime you use db2text
to create and/or drop indexes, you also manually check
the content of the resulting ctedem.dat
file too.
One easy check, that simply looks for duplicates, would be the following:
grep -v '^#' ctedem.dat | cut -d' ' -f9 | sort | uniq -c | sort -n | grep -v '^ *1 '
This will output the names of the indexes that have duplicate entries, preceded with a count of how many times each index occurs in the file. For example, when executed on my original ctedem.dat file, the output looks like this:
2 "DB2INST1"."COMPANIES_NAME_IDX"
2 "DB2INST1"."EMAIL_ATTACHMENTS_TEXT_IDX"
2 "DB2INST1"."JOBS_TITLE_IDX"
2 "DB2INST1"."PEOPLE_FIRSTNAME_IDX"
2 "DB2INST1"."PEOPLE_SURNAME_IDX"
indicating that each of those five indexes are listed twice in the ctedem.dat
file. If, however, the ctedem.dat
file contains no duplicates (as should be the case), then the above command won't output any text.
Another simple, yet valuable, check would be simply to verify that the number of non-comment entries in the ctedem.dat
file is equal to the number of indexes you have created. In the case of my project, I happen to know that there are
exactly (for now) 9 NSE indexes. So, it's simply a matter of executing something like:
grep -v '^#' ctedem.dat | wc -l
and ensuring that the result is 9.
Let me just finish by saying, once again, that the IBM DB2 Net Search Extender (NSE) is well and truly, without doubt, the single worst aspect of DB2 (if you hang around me, then you'll hear me say that quite frequently). However, IBM have begun importing the NSE capabilities directly into DB2 under the moniker "DB2 Text Search", so hopefully (fingers crossed tightly, but breath not held) that will resolve this piece of disappointing software... did that sound too harsh? ;)