Linux Mail Forwarding

Posted by Chief on Aug 23, 2010 in Gotchas
No Comments

If you want to forward mail on a linux machine that you happen to have an account on, follow these simple steps.

touch ~/.forward
chmod 644 ~/.forward
vi ~/.forward

Contents of ~/.forward should be a comma or newline separated list of email addresses to forward mail to.  The following are correctly formatted: .forward files and a brief description of each.

Forward all local email to email@example.com:

email@example.com

Forward all local email to both email@example.com and alternate@domain.com:

email@example.com, alternate@domain.com

Use the local mail spool, keep a copy in the user’s ~/archive/mail file, and forward a copy to email@example.com:

\user, "/home/user/archive/mail", email@example.com

The permissions of the .forward file must be read-only for group and other. Failure to secure your .forward file will cause sendmail to ignore its existence.

GOTCHA!

Tags: , , , ,

Big MySQL Table? Watch the keyfile Length

Posted by Chief on Aug 2, 2010 in Gotchas
No Comments

I made some large tables (around 3-4 billion records each) and then tried to create indexes on one column in each of them. I found that MySQL stopped at a seemingly arbitrary maximum index file size (.MYI file) for both of them. When I tried to open either table, I received an error message “ERROR 1016 (HY000): Can’t open file: ‘mytable.MYI’ (errno: 144)” indicating that the index file was crashed.

CHECK TABLE mytable QUICK reported ‘warning : Keyfile is almost full, 17179867136 of 17179867136 used’ Then myisamchk -dv mytable reported similar information under ‘Max keyfile length,” and reported “Keyfile pointer (bytes): 3′

After a little digging around, I realized that a 3-byte keyfile pointer only allows the index file to hold 2^24 blocks (about 16 million blocks of 1024 bytes each). My index file was holding about 110 keys per block (e.g., each record needed 4 bytes for the key value, plus 4 bytes for the datafile pointer, and maybe one byte for null/housekeeping, and then each block kept a little more empty space). So the 3-byte keyfile pointer only allowed MySQL to index about 1.8 billion records. Then it gave up, leaving a corrupted index file.

I have found no documentation for how MySQL decides how big a keyfile pointer to use in the .MYI file. I had no trouble adding 3-4 billion records to the MYD file, so it didn’t occur to me that there would be a problem with the MAX_ROWS clause of the CREATE TABLE command (which I hadn’t specified). But that turned out to be the problem.

I recovered my data table without the index file, then issued ALTER TABLE MAX_ROWS=4000000000, ADD INDEX (mykey); and now it looks like everything will be OK.

Here’s how I got my table back, without the index file (similar to what’s described above):

  1. make a backup of the data file (mytable.myd), just in case
  2. create a new empty table with the same structure as the existing table, but no index keys.
  3. copy the .FRM and .MYI files from the new (empty) table over the existing mytable.frm and mytable.myi files.
  4. issue REPAIR TABLE mytable USE_FRM; It is very important to include the USE_FRM clause. That way, MySQL knows to make a new (empty) .MYI file that matches the .MYD file, rather than truncating the .MYD file to match the .MYI file. You will eventually get a message along the lines of “Number of rows changed from 0 to xxxx”.
  5. Now you have a working table, with no indexes. Then you can set MAX_ROWS to something appropriate, and try again to make the indexes.

Tags: , , , , , ,

Files Ending in .php.html Unexpectedly Being Processed by the PHP Engine

Posted by Chief on Jul 29, 2010 in Gotchas
No Comments

Apache/2.2.3 (Red Hat), PHP 5.1.6 and phpDocumentor v1.4.3 weren’t getting along. phpDocumentor was generating HTML with filenames of the form script.php.html. Apache’s mod_php wanted to interpret script.php.html as a PHP script and was throwing errors about improper formatting:

PHP Parse error: syntax error, unexpected T_STRING in /var/www/default/docs/out/lib/lib/_php---obj---FFT.php.html on line 1, referer:...

I wanted script.php.html to be treated as an HTML file and not be processed by the php engine.  This double-extension was causing me grief.  The docs claimed that only files ending in the extension will be handled by the AddHandler command.  I was incredulous of this claim, especially in light of Apache’s ability to do content negotiation with those .var language files.

Q: Why was this happening? I first guessed it may have been due to mod_mime, but quickly ruled that out.  I then guessed it was the MultiView option… Maybe, this is one mechanism that governs content negotiation… The documentation claims:

# The index.html.var file (a type-map) is used to deliver content-
# negotiated documents.  The MultiViews Option can be used for the
# same purpose, but it is much slower.

This statement lead me to suspect that my problem may actually be caused by an issue with the AddHandler option, since an AddHandler command must be executed to associate type-map with that .var extension.

Ah me, time is money, and in the end, I actually didn’t diagnose the problem, but I did discover (by trial and error) a workaround.

In file /etc/httpd/conf.d/php.conf, I surrounded

AddHandler php5-script .php
AddType text/html .php

with

<Files ~ "\.php$">
  AddHandler php5-script .php
  AddType text/html .php
</Files>

Now, only files explicitly ending in “.php” will be treated as a php5-script.  Take that!

Tags: , , , , , ,

PHP 5.1+ Date vs Strftime Timezone Annoyance

Posted by Chief on Feb 21, 2010 in Gotchas
No Comments

In the old PHP4 days, you could change the default timezone by: putenv("TZ=America/Los_Angeles");. In php5, you can still do this and it’ll work for strtotime, strftime, gmstftime (maybe more). It will not work for methods date and gmdate. For those, starting in version 5.1, you’ll need to call date_default_timezone_set("America/Los_Angeles");. This is just another one of those annoying things that make PHP a dying language.

Together, to be cross-version compliant:

putenv("TZ=America/Los_Angeles");
if( function_exists("date_default_timezone_set") ) { 
 date_default_timezone_set("America/Los_Angeles");
}

We need both to be reverse-compatible with PHP4.

Tags: , , , ,

Copyright © 2010 cat brain.log | less All rights reserved.
Shades v1.2 theme from BuyNowShop.com.