Category Archives: Sysadmin

MSSQL and ON UPDATE

I had to add a column to a database table on an MSSQL server today. It had to have the most recent update/insert time that the row was inserted/updated. MySQL has a very easy way of doing this with a TIMESTAMP column type, with a DEFAULT value of CURRENT_TIMESTAMP, and then also an additional ON UPDATE CURRENT_TIMESTAMP clause in the column definition to auto-update the value when the row is updated.
So I thought that if MySQL could do it, so should MSSQL be able too, right? Wrong. I’m not expert in MSSQL, I know MySQL fairly well, so my first surprise was to find out that the TIMESTAMP column type in MSSQL is *so* not the same as in MySQL, and in fact is rather completely useless in this example.

The solution turned out to be external to the table definition, by using a trigger.
So here’s how you update a column in your table with the current time whenever that row is update. I’m assuming you know your way around MSSQL and it’s multitudes of tools available, so I won’t be giving you screenshots.

First, add a column to your table as either a DATETIME or SMALLDATETIME, make the default value be: (GETDATE())
The default value takes care of setting the value of the column to the current date/time when a new record is inserted.

Then, add a trigger onto your table, that looks similar to this:

CREATE TRIGGER trg_updateLastUpdated ON [dbo].[your_table_name]
FOR UPDATE
AS
if not update(last_updated)
UPDATE your_table_name
SET last_updated = GETDATE()
FROM your_table_name
INNER JOIN Inserted
ON your_table_name.unique_id = Inserted.unique_id

And that’s that. The trigger makes sure to check that it’s not the last_updated column’s UPDATE that triggers the trigger, as without it, it will cause some nasty recursion to happen.
Your INNER JOIN can be on multiple columns too, if you have more than one column that is required to uniquely identify the single row that you’re updating.

Yes, you could probably update the last_updated column’s value from within whatever code you’ve got, that is an alternative, depending on exactly what you use that column for.
Anyway, this solution worked for me. Did it work for you?

Hoops in the Air -OR- How I managed to upgrade Adobe Air to Version 1.5 on Ubuntu 8.10 and still get to use my favourite Air applications

Adobe AirUPDATE: I recently had issues with Air and Twhirl again, and thanks to @smmehadi I found there was two steps I didn’t do to *completely* get rid of all traces of Air. I added that step into the list below. For reference, here’s the official Adobe Air Linux troubleshooting page.

Adobe recently released the final version of their Adobe Air 1.5 desktop web application framework for Linux. It was a great day, and a lot of people immediately upgraded. Problems occurred immediately when people tried to run or upgrade their Air applications, and found Air was complaining about damaged applications or .air files.
I had the same, I couldn’t install the latest version of Twhirl, my number one choice for Twitter client. After several attempts and to-ing and fro-ing on Google and reading forums and even bitching about it on Twitter, I finally managed to get Twhirl running on Ubuntu, using Adobe Air 1.5
Here’s how I did it using Ubuntu (YMMV):

  • Firstly, to make 100% that you’re going to succeed here, make peace with the fact that you’re going to have to reconfigure whatever Air applications you had.
  • Update your system’s repositories to the latest by running “sudo apt-get update” and then “sudo apt-get dist-upgrade”
  • Uninstall Adobe Air. There’s an uninstall option on your Applications menu.
  • Delete any Air applications you may have installed, they usually reside in /opt/ on the disk.
  • Delete your ~/.appdata/ folder
  • Delete your ~/.adobe/AIR folder – NEW STEP
  • Delete your ~/.macromedia/Flash_Player/www.macromedia.com/bin/air* folders – NEW STEP
  • Make sure there is no /opt/Adobe/ folder, delete it if it’s there.
  • Run “sudo apt-get autoremove adobeair1.0” in a Terminal window.
    This will likely moan about packages having unmet dependencies. This is fine.
  • Run “sudo apt-get -f install”, this will list the Adobe Air applications you remove in a previous step here, press Enter to allow Apt to clean up the files.
  • Your system should now be suitably void of all Adobe Air traces.
  • Head to http://get.adobe.com/air/ and download the AdobeAIRInstaller.bin file.
  • In a Terminal window, make the file executable by running “chmod +x AdobeAIRInstaller.bin” in a Terminal window
  • Run the file with “./AdobeAIRInstaller.bin” or double-click the file in your Nautilus/File Browser window
    This will install the base Adobe Air 1.5 framework
  • After Air is finished installing, you need to make sure you have the latest Adobe Flash plugin installed. In a Terminal window, run this “sudo apt-get install flashplugin-nonfree”
  • You are now ready to install your favourite Air applications. I installed Twhirl.
  • Head to www.twhirl.org – Notice that, as of writing, the Twhirl guys made a special Linux build of the Twhirl client (Currently it is here http://www.twhirl.org/files/twhirl-0.8.7-air11.air)
  • Allow Air to Open and install the application

And that’s it, it might seem like many steps, but really, it’s just a simple way of cleansing your system from any unwanted Air leftovers of previous installations, and installing the latest version of Air and your favourite Air applications.
It’s worth noting too, that this seems to only affect currently installed Air applications. Any new applications that I installed after upgrading to Air 1.5 seemed to work just fine, so it seemed to have something to do with either leftover config files, or application files, or possibly the way Adobe Air interfaces with the Apt package management setup. I have a suspicion it’s the latter, but I don’t know the system well enough to provide proof. But at least what I did above worked. 🙂

Fixing Windows MBR with Ubuntu 8.04.1 Live-CD

UPDATE: This works on Ubuntu 8.10 Live-CD too, just boot the livecd and execute the install-mbr command

I’ve fixed MBRs before, using both the Windows install CD, and also using grub from an Ubuntu Live-CD. Today, neither of these worked on an HP 6710b laptop, where an Ubuntu partition (which contained grub) was removed (In favour of running Ubuntu inside Virtualbox). The Windows XP Professional CD didn’t detect any harddrives to fix, and grub kept on giving a “That is not a valid block device” error.

Many Google search results later, I found an article on arsgeek that showed how to use an Ubuntu package called ms-sys to put the MBR back. Boot the CD, add the universe repository, apt-get update, install ms-sys, run ms-sys. Sounded simple. After waiting for the update to happen, I finally try to install ms-sys, to no avail.

More Google search results, and it turns out that ms-sys was removed from Debian Unstable, and thus removed from Ubuntu Hardy’s repositories, due to “Unresolved licensing issues”.

Luckily, a comment on the bug entry asking why ms-sys was removed, pointed me to the mbr Ubuntu package that provides the same functionality as ms-sys.

So, how *does* one fix a Windows MBR with an Ubuntu 8.04.1 Live-CD? Simple (Works with older Live-CDs too, from Dapper onwards):

  • Boot from the Live-CD
  • Open up a Terminal and run: sudo vi /etc/apt/sources.list
    And uncomment the 6 ‘universe’ repositories at the bottom
  • Run: sudo apt-get update
    to update the local repositories
  • Run: apt-get install mbr
    to install the mbr package
  • Run: install-mbr /dev/sda
    where /dev/sda is your primary boot drive
    This installs a default MBR to that drive

Easy.
Reboot and you’re set.
No hassling with grub or lilo or dd’ing some dodgy MBR downloaded from some site.
Yet another example of how Ubuntu saved some other commercial OS from destruction. (Previously Ubuntu helped me save a SUSE 10 machine’s harddrive…)

Pity about having to update to the universe repositories first, the mbr package really should be part of the live cd.
[ad]

Perl, FreeTDS and Cron issues

While converting some dodgy nagios-commands into cron scripts today, I came across an age-old issue when scheduling the final script in cron: The script works perfectly when running it on the command-line, but fails miserably when cron runs it.

The usual answer here is “Check the environment variables”.

The error I was getting was from perl’s DBD library when trying to connect to the MSSQL database:

failed: (DBD: dbd_db_login/SQLSetConnectOption err=-2)

Hunting around I wasn’t 100% sure what environment variables I needed.
Turns out we’re using FreeTDS to get Linux to talk to an MSSQL server.

I tried several of the environment variables I found in my shell’s environment, and a mix of several, and as it turns out I was missing only one:

PERL_DL_NONLAZY=1

Seems the previous Windows Admin Guy came across the same problem, didn’t document it anywhere, but did add the variable to the Linux machine’s global profile. This worked while Nagios was calling the perl-script, but cron runs with a nice clean environment, so didn’t help there.
So just export the PERL_DL_NONLAZY variable before you run your perl-script, and voila, there it is.