Wednesday, June 20, 2007

Thoughts on (Un)checked Exceptions

Brian Goetz shares his thoughts on the (recurring) idea of removing checked exceptions from the Java language in a future version, because they tend to make code too ugly to read or are just considered a "failed experiment".

I personally count myself to the faction of people in favor of checked exceptions, because I believe they can certainly make people think more about error handling than they usually tend to. It may be harsh to say that, but in my opinion people - developers maybe even more - somethimes need to be forced to do unpleasant things. Of course checked exceptions can be a pain in the neck when you need to create e. g. Runnables, however in those cases you can still resort to throw an unchecked one . While this is a somewhat ugly technique you nevertheless are forced to think about error handling.

I suggest reading his proposals on what could be done to ease the symptoms. I mostly agree with the 2nd group of people and like the idea of having closures to better encapsulate all sorts of resource management hassles. Groovy has some nice examples of this, e. g. reading from a file and implicitly having all the boilerplate taken care of. To get some background on closures in Java, have look at the closures related posts on Neal Gafter's blog.

Concerning (checked) exceptions in general you might want to have a look (or better an ear) to an interview with Anders Hejlsberg - the principal mind behind Delphi and more recently .NET's C# language. You can find it in a series called "Thinking in Code" on Bruce Eckel's blog.

Sunday, June 17, 2007

Download Youtube Videos (and Google video)

Maybe this is obvious, but it was new to me. :)

Today I skimmed through the jroller.com homepage and found an article on Valerio Schiavoni's blog about revision control systems. He embedded a link to a video on YouTube showing Linus Torvalds giving a speech at Google about git and why he thinks it's better than other revision/software control systems.

When I started to watch I realized I would not have time to watch it to the end. So I wanted to save it locally and watch it later, without having to be online again. So I googled for "download youtube videos" and the first three matches all pointed to one sort or other of special download tools.

Turns out you do not really need anything like that. By chance I found the completely downloaded video file in the /tmp directory named something like FlashRItWZO. I tried some video on Google video, too, works fine as well. The files all start with "Flash" and are then followed by some random part.

You just have to wait until the whole video is buffered. You can then copy the file from the /tmp directory to some more permanent location. On Linux mplayer happily plays them.

One caveat needs to be remembered however: If you want the whole video you must not seek through it while it is still streaming. Otherwise you will end up with just the parts you saw/that were buffered. On the other hand you can of course use this to only store a part of a longer video, in case you do not need the whole thing.

Wednesday, June 13, 2007

MySQL server_errno=1236 when disk full

Yesterday I was asked for help concerning a replication problem with one of our test systems. My colleague had already installed a fresh dump he had created with mysqldump ... --master-data. The dump looked ok and contained a master configuration statement:

...
CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000127',MASTER_LOG_POS=4462223;
...

The slave was provided with the correct user, password and host name for this master. Nevertheless issuing a START SLAVE did not work. In the slave .err file we found this:

 
...
050327 20:54:51 [ERROR] Error reading packet from server: Client requested master to start replication from impossible position (server_errno=1236)
050327 20:54:51 [ERROR] Got fatal error 1236: 'Client requested master to start replication from impossible position' from master when reading data from binary log
...

After some fiddling around and searching the net for solutions we had a look at the server as well. SHOW MASTER STATUS revealed seemingly correct values and SHOW MASTER LOGS also listed several binlog files, up to the one mentioned above (127).

Only by looking at the Windows console of the server we found out what was wrong. Upon logging in the operating system popped up a nice balloon message about "Low Disk Space On Drive E:". In fact low was slightly understated: The drive was full up to the last byte.

Interestingly MySQL happily moved the current position counter in the output of SHOW MASTER STATUS forward, even though the file could not be written. The manual chapter on How MySQL Handles a Full Disk claims that the server should wait until there is enough space available again, and I remember having seen some "Waiting for someone to free space" before. I will have to take a look into this again and file a support request if I cannot find an explanation.

Saturday, June 09, 2007

Visualize hard disk temperature with gnuplot

When the kernel issue I blogged about hit me I first suspected a(nother) defective hard disk. I opened the case to find my 250GB Samsung Spinpoint SP2504C so hot that I could barely touch it without burning my fingers. Mentally preparing to reinstall Ubuntu on a disk yet to be bought I remembered that this disk was not needed to boot at all, because it just contains data files. (Anyone else losing track of what is stored where with the disk sizes these days?)

So I decided to just let everything cool down and then start again - in the meantime I had noticed that the latest kernel update had caused the effect and that starting with 2.6.20-15-386 would work. Once I was back to my desktop I installed some packages for hardware monitoring:

ds@yavin:~$ sudo apt-get install hddtemp sensors-applet lmsensors

Once they (and their dependencies) had all been installed I first started toying with hddtemp:

ds@yavin:~$ sudo hddtemp /dev/sd[abc]
/dev/sda: IC35L080AVVA07-0                        : 46°C
/dev/sdb: SAMSUNG SP2504C                         : 34°C
/dev/sdc: SAMSUNG HD403LJ                         : 32°C
ds@yavin:~$ 

This little script collects the data from disks /dev/sd[abc] and stores them in a space separated format into a logfile:

#/bin/bash
logfile=/var/log/hddtemp.log
timestamp=$( date +%T );
temps=$( hddtemp /dev/sd[abc] | awk -F: ' { print $3 } ' | cut -c2-3 | tr "\n" " " );
echo "${timestamp} ${temps}" >> ${logfile}

It is invoked via cron once per minute. This was added to /etc/crontab

*/1 *    * * *   root   /usr/local/bin/sht.sh 

This data can now be plotted graphically using gnuplot:

#!/usr/bin/gnuplot -persist
#
#    
#       G N U P L O T
#       Version 4.0 patchlevel 0
#       last modified Thu Apr 15 14:44:22 CEST 2004
#       System: Linux 2.6.20-15-386
#    
#       Copyright (C) 1986 - 1993, 1998, 2004
#       Thomas Williams, Colin Kelley and many others
#    
#       This is gnuplot version 4.0.  Please refer to the documentation
#       for command syntax changes.  The old syntax will be accepted
#       throughout the 4.0 series, but all save files use the new syntax.
#    
#       Type `help` to access the on-line reference manual.
#       The gnuplot FAQ is available from
#               http://www.gnuplot.info/faq/
#    
#       Send comments and requests for help to
#               <gnuplot-info@lists.sourceforge.net>
#       Send bugs, suggestions and mods to
#               <gnuplot-bugs@lists.sourceforge.net>
#    
# set terminal x11 
# set output
unset clip points
set clip one
unset clip two
set bar 1.000000
set border 31 lt -1 lw 1.000
set xdata time
set ydata
set zdata
set x2data
set y2data
set timefmt x "%H:%M:%S"
set timefmt y "%H:%M:%S"
set timefmt z "%H:%M:%S"
set timefmt x2 "%H:%M:%S"
set timefmt y2 "%H:%M:%S"
set timefmt cb "%H:%M:%S"
set boxwidth
set style fill empty border
set dummy x,y
set format x "% g"
set format y "% g"
set format x2 "% g"
set format y2 "% g"
set format z "% g"
set format cb "% g"
set angles radians
unset grid
set key title ""
set key right top Right noreverse enhanced box linetype -2 linewidth 1.000 samplen 4 spacing 1 width 0 height 0 autotitles
unset label
unset arrow
unset style line
unset style arrow
unset logscale
set offsets 0, 0, 0, 0
set pointsize 1
set encoding default
unset polar

unset parametric
unset decimalsign
set view 60, 30, 1, 1
set samples 100, 100
set isosamples 10, 10
set surface
unset contour
set clabel '%8.3g'
set mapping cartesian
set datafile separator whitespace
unset hidden3d
set cntrparam order 4
set cntrparam linear
set cntrparam levels auto 5
set cntrparam points 5
set size ratio 0 1,1
set origin 0,0
set style data points
set style function lines
set xzeroaxis lt -2 lw 1.000
set yzeroaxis lt -2 lw 1.000
set x2zeroaxis lt -2 lw 1.000
set y2zeroaxis lt -2 lw 1.000
set tics in
set ticslevel 0.5
set ticscale 1 0.5
set mxtics default
set mytics default
set mztics default
set mx2tics default
set my2tics default
set mcbtics default
set xtics border mirror norotate autofreq 
set ytics border mirror norotate autofreq 
set ztics border nomirror norotate autofreq 
set nox2tics
set noy2tics
set cbtics border mirror norotate autofreq 
set title "Plattentemperaturverlauf" 0.000000,0.000000  font ""
set timestamp "" bottom norotate 0.000000,0.000000  ""
set rrange [ * : * ] noreverse nowriteback  # (currently [0.00000:10.0000] )
set trange [ * : * ] noreverse nowriteback  # (currently ["31/12/99,23:59":"01/01/00,00:00"] )
set urange [ * : * ] noreverse nowriteback  # (currently ["31/12/99,23:59":"01/01/00,00:00"] )
set vrange [ * : * ] noreverse nowriteback  # (currently ["31/12/99,23:59":"01/01/00,00:00"] )
set xlabel "Time" 0.000000,0.000000  font ""
set x2label "" 0.000000,0.000000  font ""
set xrange [ "00:00:00" : "23:55:00" ] noreverse nowriteback
set x2range [ * : * ] noreverse nowriteback  # (currently [-10.0000:10.0000] )
set ylabel "Temperature (C) " 0.000000,0.000000  font ""
set y2label "" 0.000000,0.000000  font ""
set yrange [ 20.0000 : 60.0000 ] noreverse nowriteback
set y2range [ * : * ] noreverse nowriteback  # (currently [-10.0000:10.0000] )
set zlabel "" 0.000000,0.000000  font ""
set zrange [ * : * ] noreverse nowriteback  # (currently [-10.0000:10.0000] )
set cblabel "" 0.000000,0.000000  font ""
set cbrange [ * : * ] noreverse nowriteback  # (currently [-10.0000:10.0000] )
set zero 1e-08
set lmargin -1
set bmargin -1
set rmargin -1
set tmargin -1
set locale "C"
set pm3d scansautomatic flush begin noftriangles nohidden3d implicit corners2color mean
unset pm3d
set palette positive nops_allcF maxcolors 0 gamma 1.5 color model RGB 
set palette rgbformulae 7, 5, 15
set colorbox default
set colorbox vertical origin 0.9,0.2 size 0.1,0.63 bdefault
set loadpath 
set fontpath 
set fit noerrorvariables
plot '/var/log/hddtemp.log' using 1:2 with line title "hda", '/var/log/hddtemp.log' using 1:3 with line title "hdb", '/var/log/hddtemp.log' using 1:4 with line title "hdc"
#    EOF

Running the gnuplot script above displays a graph with the temperature curves for my three hard disks. You will need to modify both scripts to match your disk configuration. Furthermore logrotate should be configured to start a new file every day, otherwise the graph will look somewhat strange.

sample graph

You need not care about the

sh: kpsexpand: not found
sh: kpsexpand: not found
sh: kpsexpand: not found
sh: kpsexpand: not found

messages when you run the script. This seems to be a packaging problem with gnuplot. kpsexpand seems to belong to the tetex-package, which however is not really needed for it to work.

Additionally I have installed the Gnome Sensors applet that now continuously displays data from several sensors, including CPU temperature and fan speeds.

BTW: The temperaturs above were taken after I installed a fan in the front panel of my PC's case. Before that all disks were 10-15°C warmer, bringing them close to their specified limits.

Monday, June 04, 2007

Beware of Ubuntu Kernel 2.6.20-16!

Anyone using Ubuntu Feisty Fawn should not install the kernel update to 2.6.20-16! It comes as a security update, but it includes some nasty trickery with the ATA/SATA drivers. After I installed it I could not boot anymore, because for some reason the drive names had changed!

All the SATA drives that had /dev/sdXX names before were now called /dev/hdXX. Even though my /etc/fstab only contains "by-uuid" entries, all but the PATA boot drive could not be accessed.

I already suspected a hardware defect, because booting without the splash screen showed "lost interrupt" errors. I only got skeptical when I read it was on drive /dev/sdg which I just plain do not have!

Unplugging both SATA drives at least let me boot into the system again. From what I read in Launchpad Bug #116996 booting with the previous version 2.6.20-15 should work in the meantime.

I have to admit I am pretty pissed off by Ubuntu at the moment. I really love the work they do, however sometimes they seem to be a little too fast with updates (remember the troublesome X11 update some months ago) that are critical to the system. Maybe I would not be so angry about e. g. the sound card not working properly, but come on people, changing hard disk drivers silently as part of an unrelated security update?!

The bug is several days old already and Debian already has it fixed. However for some reason there does not seem to be much movement from Ubuntu...