MySQL through SSH tunnel

September 3rd, 2009

Sometimes we face a problem when we have SSH access to the server, but not to MySQL.
Here is a simple workaround - SSH tunnel:

ssh -f -N -L LOCAL_PORT:127.0.0.1:3306 USER@HOST

This command allows you to map remote port to the local one via SSH tunnel.

  • LOCAL_PORT - local port to map to
  • USER - SSH username
  • HOST - remote host

Surely, you can map other ports as well.

When you mapped the port, you can connect to MySQL using your favorite client (you need to specify LOCAL_PORT as MySQL server port in connection settings).

Yuriy Zisin Misc , , , ,

Application semaphores using MySQL

April 13th, 2009

Many tasks require some application part to run in one instance per time, such as mail delivery cron job. And each time developers should invent some mechanism to determine if another copy is running. Usually no of these mechanisms are 100% reliable.

The solution is already found by MySQL development team. It is “named locks”.

Application can try to acquire a named lock on its start and check if another copy is running.

How can it be implemented:

$res = mysql_query("SELECT GET_LOCK('lockname', 2)");
$result = mysql_fetch_array($res);
if (!intval($result[0])) {
    echo “Cannot run until previous instance finish!”;
    exit;
}

// Do anything we need

mysql_query(”SELECT RELEASE_LOCK(’lockname’)”);

What we get using this mechanism:

  • GET_LOCK will fail if a lock with specified name already set and script can stop;
  • Script can work as long time as it needs;
  • RELEASE_LOCK will free acquired lock and script will run successfully next time;
  • If the script will fail with fatal error, time restriction or somehow else, MySQL will free its lock automatically on connection close;
  • No additional files, table records, no stupid checks. Everything is done in 2 queries;
  • We can be 100% sure another copy is running now, no lost locks;

Note: All the above is true if you use only one lock per script (and probably without persistent connection) because callng GET_LOCK second time during the same session will release previous lock. This feature is very usefull for cronjobs.

To read more about these functions - visit MySQL Manual

Yuriy Zisin Development , , , ,

Broadcast messaging

March 9th, 2009

I’ve never tried to send and receive broadcast messages before, so I faced one fun problem. It’s easy to open UDP socket and send broadcast message and there are lot examples you can find. It’s also easy to find out how to catch the broadcast message. But what I did - I run sender and receiver code on the same machine and was trying to make it work. I failed just because the broadcast packet doesn’t get returned to the sender machine. So, save you time - use different machines for testing broadcasts ;-)

Yuriy Zisin Development ,

PHP DOMDocument class and HTML entities

February 19th, 2009

DOMDocument class behaves strange sometimes. It could omit some entities like “ and some valid UTF-8 characters (it also may do so for other encodings). This probably could be fixed by using own DTD, but there is a simple way too. Each HTML entity has its binary code, so DOMDocument will export your entities correctly if you replace the entities by the appropriate codes. I have a small list of them. By using the following function you can avoid symbols loss:

function parseEntities($string) {
    $entities = array (
        "auml" => "ä",
        "ouml" => "ö",
        "uuml" => "ü",
        "szlig" => "ß",
        "Auml" => "Ä",
        "Ouml" => "Ö",
        "Uuml" => "Ü",
        "nbsp" => " ",
        "Agrave" => "À",
        "Egrave" => "È",
        "Eacute" => "É",
        "Ecirc" => "Ê",
        "egrave" => "è",
        "eacute" => "é",
        "ecirc" => "ê",
        "agrave" => "à",
        "iuml" => "ï",
        "ugrave" => "ù",
        "ucirc" => "û",
        "uuml" => "ü",
        "ccedil" => "ç",
        "AElig" => "Æ",
        "aelig" => "Ŋ",
        "OElig" => "Œ",
        "oelig" => "œ",
        "angst" => "Å",
        "cent" => "¢",
        "copy" => "©",
        "Dagger" => "‡",
        "dagger" => "†",
        "deg" => "°",
        "emsp" => " ",
        "ensp" => " ",
        "ETH" => "Ð",
        "eth" => "ð",
        "euro" => "€",
        "half" => "½",
        "laquo" => "«",
        "ldquo" => "“",
        "lsquo" => "‘",
        "mdash" => "—",
        "micro" => "µ",
        "middot" => "·",
        "ndash" => "–",
        "not" => "¬",
        "numsp" => " ",
        "para" => "¶",
        "permil" => "‰",
        "puncsp" => " ",
        "raquo" => "»",
        "rdquo" => "”",
        "rsquo" => "’",
        "reg" => "®",
        "sect" => "§",
        "THORN" => "Þ",
        "thorn" => "þ",
        "trade" => "™"
     );

    foreach ($entities as $ent=>$repl) {
        $string = preg_replace('/&'.$ent.';?/m', $repl, $string);
    }

    return $string;
}

This list contains not all the entities, but it is easy to inroduce new ones without any other code influence.

Yuriy Zisin Development , , , ,

array_merge_recursive problem in PHP 5.2.5

February 19th, 2009

I faced a problem with Plugin Everywhere project some time ago. During the deep debugging I found that the code doesn’t have any problem, but PHP had.

PHP 5.2.5 has a problem with array_merge_recursive function. It was grouping NULL values into the one. I even found this bug here. Plugin Manager uses that function for queues bulding, so this caused handlers call problem.

It’s just the interesting fact, so be careful ;)

Yuriy Zisin Development , , ,

Hello World!

February 16th, 2009

It’s a tradition. When someone starts studying programming discipline the first program usually outputs ‘Hello world’.

Keeping the tradition I start my blog by ‘Hello world!’ post :)

Everything about me you can see at http://www.yzisin.com/, so just blog is here.

Yuriy Zisin Misc