Thursday, February 28, 2008

New Forge: Missing the bug!

Forge 2.0 was announced yesterday, and Jay and I were bracing ourselves for an avalanche of bugs, which did not come.
When Bug#34916 (Login not working on new forge site) was reported, I thought nothing of it. It was simply the wrong environment. The reporter could not log in, because he did not have an account.

I explained the problem, and felt good about it.
Sometimes I experienced reporting a bug and being told that it was intended behavior, not a bug, read the manual, thanks for writing, and that was it. So dry and clueless. Not inspiring for a further analysis.
So I took some minutes to explain what had happened, before closing the bug with the fatal words.
And the reporter, Diego Medina, wrote back, saying that indeed he did not have an account on wiki, and thus there was no bug. However, he reported a lack of message on a failed login, which made me suspicious.
So I tried logging in with a non existing account, and I was refused. Then I tried my account, with a wrong password. To my surprise, I was admitted. Then I logged out and I logged in again as Jay Pipes, with a wrong password, of course, because I don't know it.
Bingo! The system accepted my login. I was logged in as Jay. So the Forge was not checking the password at all. Something must have gone awry during the latest bug fixes.
I alerted Jay (not before changing his profile to a "lazy guy", though!) and he fixed the vulnerability in a few minutes. Apparently nobody noticed.
I found out the security hole thanks to Diego's suggestion. He actually found the bug, but he did not realize how serious it was. I feel positive vibes because I triggered Diego's comment with my explanation.
Note to bug verifiers (not all of them, but someone): sometimes, being kind can win you back some benefits!
Thanks Diego, for sending me to the right direction!
Community, please keep testing the new Forge!

Testing the new MySQL Forge


As Jay just just announced, we are launching Forge 2.0. This is a one man show, and that man is Jay. He designed and implemented the new Forge (and the old one, for that matter) almost entirely on his own. He fixed countless bugs, and after much suffering the community can now experience the new look and feel and the new cool features.
Thanks, Jay!

Now, if you want to help, enjoy the new Forge and report problems in our bugs system. Let me show you the general picture first,a nd then we'll see what to test.

A quick tour

There are many new features in the Forge:

  • The login. In the old Forge, you had two logins, one for the main forge and one for the wiki. In the new one there is only one login. If you had an account, use your email address and the wiki password to access the Forge.
  • The people section gives information on the user, and a summary of his/her contributions;
  • All sections can get votes. You can enter a vote from 1 to five for any project, tool, worklog.
  • The old snippets section is now called tools and code, to better describe what it contains. The code supports more languages than before (86 of them, actually!).
  • Comments. You can comment on any object (project, tool, worklog), using some HTML and special code tags.
  • The wiki is fully integrated, with the same look and feel, and a shared toolbar.



(Actually, I made a mistake in the example shown in this picture. I should have written "<b>bold</b> text" but you got the idea)

A testing check list


The new Forge has passed many checks, but we are sure that we must have missed something. And we know about some known bugs that we have not had time to fix, but we will tackle soon. Your help is much appreciated. If you have experience with MediaWiki and want to share your experience in fixing similar problems, by all means drop me or Jay a line, and we will be grateful.
Everyone else, you can just go through the list below, and report bugs to bugs system (Category: MySQL Forge).
  • Log in
  • edit an existing project (if you have created one before)
  • edit an existing tool (again, if you have created one before)
  • add a tag to a worklog/project/tool/person
  • search by tag
  • add a comment, using HTML or code tags
  • vote for a project/tool/worklog
  • add a new project and add tags
  • add a new tool and add tags
  • switch to the wiki, search for pages that you know in the old wiki, check that they are correct;
  • edit a wiki page
  • create a new wiki page
  • create a new user, login with this new entity, and do all the above
If that does not look enough to you, run around, and try to break things. Don't worry. We'll reload the database and fix the contents if you mess up too much.
However, remember that this is still a test environment. Everything you do will be overwritten on Monday, when we put the new Forge in production. Thus, play with it, but save important contents in the old wiki.

Troubleshooting


If your login does not work, remove all cookies related to forge1.mysql.com or forge.mysql.com and try again.
Remember that the new Forge uses the email address and the password of the old Forge wiki, not the main Forge.
One possible source of problems is when you had a different email address in the main forge and in the wiki. If that happened, we will be able to assign you ownership of the wiki pages you wrote, but not the projects and snippets. To fix that, go back to the old Forge and make sure that the email address used to login to the main forge matches the one used in the wiki, When we reload the database on Monday your previous work will be recognized. In the meantime, just create a fake account in the test forge, and enjoy the features!

Tuesday, February 26, 2008

Vim and MySQL, anyone?

On the Dev Zone there is a quick poll about your favorite IDE. The results from day one show a surprising preference for a lightweight editor, which happens to be my favorite as well.

Perhaps it's just a chance of the initial poll. We'll see in the next days.
However, it may be a good association of lightweight products. MySQL is a small, ubiquitous database server, compared to other more heavy products that need to be distributed in DVD, and the Vi family (with my favorite vim) is also small and ubiquitous.
What I loved a lot while working as a consultant is the ability of using syntax highlighting even in the most basic environments (i.e. a ssh connection on a terminal emulator) and the availability of vim in every operating system.


What's your take? Cast a vote for your favorite development environment.

Saturday, February 23, 2008

Bug or not bug? A Falcon mystery solved

Bug#33184 looked like a tough nut to crack. The initial report was quite clear. Some tests failed on Mac OS X.

I initially assumed that our testing boxes did not include the platform I was using, and informed Hakan. He tested the suite on his box, and reported success.
Too bad. Being able to reproduce a bug is the first step towards its fix. So we exchanged notes on how we compiled the sources. It turned out that I was using the optimized build, while Hakan was using a build with debug options.
I tried with debug options, and indeed, the test suite passed. However, since users are likely to adopt the optimized build, the bug was still confirmed.
More time passed. Hakan made some changes, and the test suite passed in his box, but failed in mine.
Finally, Hakan found the problem. The test suite failed because of the default gcc compiler provided by Apple. Mac OS X 10.4 and 10.5 offer gcc 4.0.1 with Xcode. Apparently, as Hakan found out, there is a bug in the exception handling of Apple's gcc.
After upgrading to gcc 4.2.2, the test suite passed without errors.
Good job, Hakan!

Thursday, February 21, 2008

Spring cleaning in MySQL supported platforms

The MySQL Lifecycle Policy determines which versions are actively supported, and for which platforms such support applies.
The basic principle is that old versions are supported for a quite long, but definitely limited period, once they have been replaced by a newer GA version. For example, since the introduction of this policy, MySQL 3.23 and 4.0 have been retired.
The policy contains also provisions for a different kind of End of Life dismissal. When support for certain platforms has been discontinued by their vendors, of the platform is not widely used, MySQL reserves the right to stop building binaries and testing code on such obsolete platforms.
The reason is simple. While hardware can be bought and stored, time is a commodity in short supply, and there is only a given amount of time that our engineers can devote to testing and supporting multiple platforms.
Therefore, it makes sense to discontinue those platforms that have few users, and dedicate some valuable time to new, emerging platforms that are more popular and widely used.
bones

For the above reasons, at the end of 2008, MySQL will discontinue some old platforms:
  • MAC OSX 10.3
  • HP-UX 11.00
  • SCO OpenServer (all versions)
  • QNX (all versions)
MySQL will continue to offer support to specific customers in these platforms, but the public builds will be abandoned as of December 31, 2008.

The above decision is based on some vendor end-of-life support, and on our surveys on platform usage.
The intention is to provide a better service to users and customers, by allowing our engineers to spend time on the more widely used systems.

Tuesday, February 19, 2008

Users Conference 2008 - latest schedule changes


If you plan to attend the MySQL Users Conference, hurry up! The early bird registration ends on February 26. It's your chance to save a few hundred dollars.
If you need some more reasons for attending, notice these late additions to the schedule:

The Falcon sessions were added just today, and my session is a replacement of "MySQL Proxy Wizardry" (but don't worry: some of its contents will be included in the MySQL Proxy Tutorial.
Did I mention that you should hurry up to save some bucks? Register now!

BTW, as a speaker, I can give a 20% discount to my friends. If you want to get one, please drop me a line by email at my_first_name AT mysql dot com.

Monday, February 18, 2008

On good coffee and acquisitions

When traveling to my parents town with my wife, we used to stop by a coffee shop on the highway, where a charming couple made good coffee with a smile. They were efficient and friendly. As soon as we were stepping out of the car, they were already preparing for our usual order (espresso and cappuccino), and they had always a joke or a funny comment for us.

Once we saw them dealing with two busloads of tourists, serving whatever they asked rapidly and cheerfully. This shop was a popular stop, always crowded.
It ended a few weeks ago. Someone decided that the location was profitable, and now the small shop has been replaced by a huge coffee+restaurant+amenities resort.
We stopped there, out of habit, shortly before my world trip. The crowd was thinner than usual. The charming couple was gone, replaced by a 4 people team, who sent us to queue at the cashier's before ordering. The coffee was awful, and the barista's attitude less than friendly. We were not impressed.
We went there again yesterday, just to give them another chance. The 4 people team has grown to 5, but the attitude and skillset have not improved. There were very few people, less than we had ever seen in that location. If you ask me, that resort is doomed. If there was any good business, it was because of the people running it, not because of a magical road junction that compelled travelers to stop there.
The lesson to learn here is simple: taking over a successful business without due thought to the people factor is risky, bordering on disastrous.
Sun seems to have this concept in mind. After the MySQL acquisition, they want to keep MySQL people in the right places. I am confident in the future, but a friendly reminder should not do any harm. :)

Thursday, February 14, 2008

Chasing elusive bugs

Since the announcement of Maria, I have been trying to use the same crashing test with Falcon, to establish conclusively if its crash recovery features are as reliable as I hope.

I tried the same test used for Maria, and after a crash, Falcon did not recover nicely. In fact, the server crashed on restart. I have not been able to repeat that behavior on Linux. Actually, I did, on a remote server that is not available to me at the moment, using an earlier revision, and I am waiting until I am back home to do some more testing with the latest tree.
However, I managed to repeat the problem with Mac OS X.
I run this script on a 6.0.5 server:

set storage_engine=falcon;
drop table if exists t1;
create table t1 (id int, b longblob) ;
insert into t1 values (1, repeat('a',1000000));
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;

When the script reaches the last line (has loaded 128 records and it's inserting the next batch), I stop the server with a vicious kill -9.
Upon restarting, the system looks under control, and I run the command that was previously interrupted:

insert into t1 select * from t1;

Here, the server crashes. I have repeated the above steps several times, and it crashes consistently on Mac OS X. On Linux, which I have on a virtual machine only (I am still on the road!) I can't repeat the crash with the current revision.
So, this is a bug, no questions about that, but not a serious one, unless I manage to prove otherwise.
Perhaps this bug is related to Bug#33517. We'll see.
If anyone has noted something similar, please let me know.

Freedom to work anywhere, really!

Singapore. Last stop of my world tour. Shortly after my arrival, the new Lunar Year began. The year of the rat was happily celebrated, and its symbols can be seen everywhere in town.


In Singapore, the Freedom To Work Anywhere @ MySQL has a new meaning. Most of the town is connected via a free wireless net. While sitting on a public bench (in cool evenings) or while enjoying food and drinks at hawker centers and cafes, you can just fire up your laptop, connect to the free wireless, and start browsing. You will need to get a (free) username and password through your mobile, but you can live with it easily.
I am on vacation, so I am not "working from anywhere", but the ubiquity of the wireless connection was hard to resist!
By the way, in case you were wondering if the Sun acquisition has changed anything substantial regarding new jobs, it hasn't. MySQL is hiring! Yes. Still. And with a plan of hiring more. So, if you were thinking of sending your CV, you can do it!

Friday, February 08, 2008

From open source to open country

During the last day of the Linux Conference Australia, I and Colin had the choice between joining the crowd for the open day, or meeting a semi-private invitation from Greg Lehey a well known icon in the open source world. He organized a hackers barbecue in his very isolated place, and we could not resist. In his original invitation, Greg said that he lives "down the road", without specifying how long the road is. It turned out that it's a 90 minutes drive, which is an indication of the relative sense of distance that you get in Australia.

In the Australian bush, Greg leads a quiet life with his wife, his horses and dogs, and a few not so distant friends, dealing occasionally with stray kangaroos invading his fields, and brewing open source beer.
The barbecue met everybody's expectations, and so did Greg's famous home brewed beer, thus stimulating that sort of hacker talk that only good food and good company can generate. The subjects ranged from the origin of the hacker's word to the openness of languages, touching virtualization, databases, operating systems, embedded libraries, and user interfaces in the process.

After lunch, we were given a demonstration of the damages kangaroos can do, along with a visual recognition of their dumpings. The peek of the visit, however, came with the open source brewery, which is controlled by a FreeBSD box, in action since 2001.

On our way back, we stopped at a wildlife center, where we had close encounters with kangaroos and koalas, before reaching back to the civilized Melbourne, where Colin gave me a crash course on "how to have fun on weekends," but I won't disclose any of its contents. Suffice it to say that Colin approaches this matter with rare professionalism, and if you need advice, you must contact him directly.

Tuesday, January 29, 2008

Introducing Maria, the new tough storage engine

Over the weekend, MySQL made available a new storage engine, codenamed Maria.
It is an improvement of MyISAM, the flagship engine, adding crash recovery to the already appreciated features of MyISAM. This release is a preview, based on MySQL 5.1 code base. The actual final implementation has not been announced yet, although it is safe to assume that it will happen in the 6.x series.
The source code is available as a bitkeeper tree.
There is some documentation, and more will follow.
What can we do with the new engine? The immediate answer is "use it as we use MyISAM, with crash recovery features".

Let's show an example, using MyISAM: (this demonstration was given live at the Linux Conference Australia during MySQL Mini-conf)

mysql [localhost] {msandbox} (test) > drop table if exists t1;
Query OK, 0 rows affected (1.14 sec)

mysql [localhost] {msandbox} (test) > create table t1 (id int, b longblob) engine=myisam;
Query OK, 0 rows affected (0.00 sec)

mysql [localhost] {msandbox} (test) > insert into t1 values (1, repeat('a',1000000));
Query OK, 1 row affected (0.02 sec)

mysql [localhost] {msandbox} (test) > insert into t1 select * from t1;
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0

mysql [localhost] {msandbox} (test) > insert into t1 select * from t1;
Query OK, 2 rows affected (0.10 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql [localhost] {msandbox} (test) > insert into t1 select * from t1;
Query OK, 4 rows affected (0.13 sec)
Records: 4 Duplicates: 0 Warnings: 0

mysql [localhost] {msandbox} (test) > insert into t1 select * from t1;
Query OK, 8 rows affected (0.26 sec)
Records: 8 Duplicates: 0 Warnings: 0

mysql [localhost] {msandbox} (test) > insert into t1 select * from t1;
Query OK, 16 rows affected (1.17 sec)
Records: 16 Duplicates: 0 Warnings: 0

mysql [localhost] {msandbox} (test) > insert into t1 select * from t1;
Query OK, 32 rows affected (2.13 sec)
Records: 32 Duplicates: 0 Warnings: 0

mysql [localhost] {msandbox} (test) > insert into t1 select * from t1;
Query OK, 64 rows affected (4.77 sec)
Records: 64 Duplicates: 0 Warnings: 0

mysql [localhost] {msandbox} (test) > insert into t1 select * from t1;

At this point, while the server is inserting data, from a different shell, we enter a vicious command:

$ kill -9 `pgrep mysqld`

which is as close as you can get to pulling your server plug. The result is disastrous.

ERROR 2013 (HY000): Lost connection to MySQL server during query
mysql [localhost] {msandbox} (test) > exit
Bye

Let's restart the server and see what has happened.

[sandbox@dsl093-167-171 maria_5_1_23]$ ./start
sandbox server started
[sandbox@dsl093-167-171 maria_5_1_23]$ ./use test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.1.23-maria-alpha Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql [localhost] {msandbox} (test) > check table t1;
+---------+-------+----------+-----------------------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+---------+-------+----------+-----------------------------------------------------------+
| test.t1 | check | warning | 1 client is using or hasn't closed the table properly |
| test.t1 | check | warning | Size of datafile is: 256004096 Should be: 128002048 |
| test.t1 | check | error | Record-count is not ok; is 256 Should be: 128 |
| test.t1 | check | warning | Found 256 parts Should be: 128 parts |
| test.t1 | check | error | Corrupt |
+---------+-------+----------+-----------------------------------------------------------+
5 rows in set (0.62 sec)

As you can see, the table got corrupted, because we pulled the plug during an insertion.
Let's do the same operation with a Maria table.

mysql [localhost] {msandbox} (test) > drop table if exists t1;
Query OK, 0 rows affected (0.15 sec)

mysql [localhost] {msandbox} (test) > create table t1 (id int, b longblob) engine=maria;
Query OK, 0 rows affected (0.01 sec)

mysql [localhost] {msandbox} (test) > insert into t1 values (1, repeat('a',1000000));
Query OK, 1 row affected (0.03 sec)

mysql [localhost] {msandbox} (test) > insert into t1 select * from t1;
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0

mysql [localhost] {msandbox} (test) > insert into t1 select * from t1;
Query OK, 2 rows affected (0.09 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql [localhost] {msandbox} (test) > insert into t1 select * from t1;
Query OK, 4 rows affected (0.29 sec)
Records: 4 Duplicates: 0 Warnings: 0

mysql [localhost] {msandbox} (test) > insert into t1 select * from t1;
Query OK, 8 rows affected (0.82 sec)
Records: 8 Duplicates: 0 Warnings: 0

mysql [localhost] {msandbox} (test) > insert into t1 select * from t1;
Query OK, 16 rows affected (1.61 sec)
Records: 16 Duplicates: 0 Warnings: 0

mysql [localhost] {msandbox} (test) >
mysql [localhost] {msandbox} (test) > insert into t1 select * from t1;
Query OK, 32 rows affected (3.16 sec)
Records: 32 Duplicates: 0 Warnings: 0

mysql [localhost] {msandbox} (test) > insert into t1 select * from t1;
Query OK, 64 rows affected (6.54 sec)
Records: 64 Duplicates: 0 Warnings: 0

mysql [localhost] {msandbox} (test) > insert into t1 select * from t1;
#
# kill -9 from another terminal
#
ERROR 2013 (HY000): Lost connection to MySQL server during query
mysql [localhost] {msandbox} (test) > exit
Bye

Here we pull the plug as in the MyISAM case, and the server dies.
On restart, the situation looks much different:


[sandbox@dsl093-167-171 maria_5_1_23]$ ./start
sandbox server started
[sandbox@dsl093-167-171 maria_5_1_23]$ ./use test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.1.23-maria-alpha Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql [localhost] {msandbox} (test) > check table t1;
+---------+-------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+---------+-------+----------+----------+
| test.t1 | check | status | OK |
+---------+-------+----------+----------+
1 row in set (0.73 sec)

So, Maria survived the crash, while MyISAM was corrupted. There is still much to do to make this engine ready for production, but it looks like an excellent start.

Slides from MySQL Proxy presentation at LCA 2008


The MySQL Proxy presentation at Linux Conf Australia 2008 was done just before lunch.
As announced, here are the presentation slides
The penguin on the above image is actually painted on my room's window glass.

Monday, January 28, 2008

Attending Linux Conference Australia - Melbourne 2008

The world tour proceeds. After Sydney, I am now in Melbourne, to attend the Linux Conf Au, hosted at Melbourne University. I am actually lodged at the charming Trinity College.

I have already met several known people and many more new people. Currently, I am getting ready for my presentation on MySQL Proxy at the MySQL mini-conf, and I have also a surprise presentation that will happen during the lighting talks.
Curious? You should be! See you tomorrow afternoon for the surprise talk!

Friday, January 25, 2008

Session on MySQL Proxy at the Linux Conf Australia


It's getting closer.
On Tuesday late morning, I will hold a session on MySQL Proxy during the MySQL MiniConf at Linux Conf Australia.
It will be an introduction to MySQL Proxy with some live demo.
If you are in Melbourne, come along!

Multiple triggers for the same event - Bug or feature?


Greetings from the Southern Hemisphere.
The World tour proceeds as planned, although with some added tasks in the meantime. The solution to the quiz announced from North America is now given from Australia. (Boy! I love the global village!)

The task was to create a series of three triggers, all associated to the same table for the same event (BEFORE INSERT). If you had a look at the manual, you would know that you can't set multiple triggers for the same event. However, there is a workaround, using the Federated engine. The solution to the quiz was already available as a comment to a bug report. My intended solution, very similar to the one provided by the winner, is reported below. Notice that I use the CREATE SERVER statement instead of hardcoding username and password in the CREATE TABLE statement. The quiz required using MySQL 5.1.22 or later for two reasons:
  • the ability of using the CREATE SERVER statement, instead of hardcoding the connection credentials. This feature was introduced in MySQL 5.1
  • The ability of using a federated table pointing to a table in the same server. This behavior was introduced in MySQL 5.1.22.
(Hubert Roksor, send me your address if you want the T-shirt, or post the address as a comment. I won't publish it, but just get the address for the shipping).

DROP TABLE IF EXISTS t1, t1_f1a, t1_f1b, t1_f1c, t1_f2a, t1_f2b, t1_f2c;
DROP SERVER IF EXISts s1;

CREATE TABLE t1 (id int, c char(100)) engine=MyISAM;

CREATE SERVER s1
FOREIGN DATA WRAPPER mysql
OPTIONS (
host '127.0.0.1',
port 5123,
database 'test',
user 'msandbox',
password 'msandbox'
);

CREATE TABLE t1_f1c (id int, c char(100))
ENGINE=FEDERATED CONNECTION='s1/t1';
CREATE TABLE t1_f1b (id int, c char(100))
ENGINE=FEDERATED CONNECTION='s1/t1_f1c';
CREATE TABLE t1_f1a (id int, c char(100))
ENGINE=FEDERATED CONNECTION='s1/t1_f1b';

CREATE TABLE t1_f2c (id int, c char(100))
ENGINE=FEDERATED CONNECTION='s1/t1';
CREATE TABLE t1_f2b (id int, c char(100))
ENGINE=FEDERATED CONNECTION='s1/t1_f2c';
CREATE TABLE t1_f2a (id int, c char(100))
ENGINE=FEDERATED CONNECTION='s1/t1_f2b';

CREATE TRIGGER bi_t1_fed_1 BEFORE INSERT ON t1_f1a
FOR EACH ROW
SET NEW.c = 'something';

CREATE TRIGGER bi_t1_fed_1b BEFORE INSERT ON t1_f1b
FOR EACH ROW
SET NEW.c = CONCAT(NEW.c, ' more');

CREATE TRIGGER bi_t1_fed_1c BEFORE INSERT ON t1_f1c
FOR EACH ROW
SET NEW.c = CONCAT(NEW.c, ' !!');

CREATE TRIGGER bi_t2_fed_1 BEFORE INSERT ON t1_f2a
FOR EACH ROW
SET NEW.id = NEW.id + 10;

CREATE TRIGGER bi_t2_fed_1b BEFORE INSERT ON t1_f2b
FOR EACH ROW
SET NEW.id = NEW.id + 100;

CREATE TRIGGER bi_t2_fed_1c BEFORE INSERT ON t1_f2c
FOR EACH ROW
SET NEW.id = NEW.id + 1000;

INSERT INTO t1_f1a VALUES (1, 'nothing');
INSERT INTO t1_f2a VALUES (1, 'nothing');

SELECT * FROM t1;
This works as expected. However, the above behavior is not in the manual. Is it a bug or a feature? Since it is not in the documentation, nor was in the original specifications, this behavior is a useful side effect. Strictly speaking, it's a bug. Pragmatically, it can be consider a feature, depending on your needs.

Wednesday, January 23, 2008

Mobile Quiz - many triggers on a single event on the same table

A few weeks after the latest useful quiz, I want to offer a funny one.
Given the following table, on a MySQL server 5.1.22 or newer,
CREATE TABLE t1 (id int, c char(100)) engine=MyISAM;
  1. Create one set of three triggers that must all be activated BEFORE INSERT.
    • Upon insertion of the values (1, 'nothing'), the first trigger should replace 'nothing' with 'something', leaving the number unchanged;
    • the second trigger should add ' more ';
    • the third trigger should add '!!'.
  2. Create one set of three more triggers, all activated BEFORE INSERT.
    • Upon insertion of the values (1,'nothing') the first trigger should add 10 to the number, leaving the text unchanged.
    • the second trigger should add 100 to the number;
    • the third trigger should add 1000 to the number;
To explain it further, it must be possible to enter a distinct INSERT command that will fire the first set of triggers, and a different INSERT command that will fire the second set of triggers.

Constraints:
  • You can only use one MySQL server. No replication, no cluster;
  • You can't use MySQL Proxy;
  • The only routines you can create are TRIGGERs. No PROCEDUREs, FUNCTIONs, or EVENTs.
  • The solution must work with a standard binary. No code changes;
  • Each insert statement must result in the creation of one and only one record in table t1.
  • No intermediate records should be created in t1 or other tables.
  • All three triggers must fire automatically as a result of a single INSERT statement.
The first one to submit the correct solution will win a T-shirt. (Note: Dipin, the winner of the previous quiz should contact me by email ( my_first_name at mysql dot com ) and give me a complete address, so I can send him/her a T-shirt).

Since I am traveling (I am about to board a plane from L.A. to Sydney), don't expect a quick reaction from me. I will eventually acknowledge your comments. Just be patient and don't assume I ran away.

The above instructions are accurate, but kind of devious (of course, or else you would not enjoy the quiz). Good luck!

Sunday, January 20, 2008

New step in the world tour and new role in a new company

What a week!
It started with a gift for all employees. A book that Lenz Grimmer has produced with great professionalism.

It is not for the general public. I am showing it here to give would-be employees one more reason to join the company. (Yes. It's business as usual. We are still hiring!)
Then the unexpected but very exciting news arrived, and perhaps a part 2 of this book won't be necessary.
(Update. Marten pointed out that this is not necessarily true, and the second part of the book will only be more exciting. Maybe so. The second part may just need a different sub-title.)
As part of the interesting changes in MySQL, there has been some side effects on me. Since Kaj is now busy being ambassador (my wife, when I explained what he'll be doing, asked if he is going to spend time with Angelina Jolie as goodwill ambassador, but it doesn't seem to be the case!) the community team needed new guidance, and the choice fell on me. So I will be coordinating the community team from now on until the smoke clears on the future of the company roles.
My world tour continues. I am now in Los Angeles, to assume my new responsibilities while on the road, as expected from a virtual company employee.

Monday, January 14, 2008

Munich-Orlando with special outfit

My world tour includes mostly warm places (Orlando, Los Angeles, Australia, Singapore), but to cover the first leg, Munich, I needed warm clothes (cover is the operative word here).
Thus, when I saw a skilled craftsman creating customized hats and scarfs, I couldn't resist.
The weather in Orlando does not require such gear. This is a view form my hotel room.
. We are going to have MySQL company meeting in this beautiful place. For now, I am just nursing my jet lag and preparing to meet a few hundred colleagues.

Thursday, January 10, 2008

World tour - step one


I am about to embark for my longest trip ever.
I will board a plane on Saturday in my hometown in Sardinia, Italy, heading to Munich. A comfortable two hours flight, to be ended with a business meeting and a traditional Munich dinner, both provided by Kaj Arnö.
The easy part of the trip ends here. From Munich, I will go to Orlando, USA, to the Company Meeting.
After the meeting, a short stopover in Los Angeles, and then the loooong jump to Sydney, which I will be wisiting for the first time. And another first time will be in Melbourne, a few days later, where I will attend the Linux Conf Au, and also present a session about MySQL Proxy during the MySQL MiniConf.

That is not the end of it, of course. I will be just half world away from home. Then I will go to Singapore for a vacation, and then back th Europe.

More travel news to come in the next days!

Wednesday, December 19, 2007

Pop quiz (with prize): generate 4 billion records

My latest quiz was quite popular, and some interesting ideas were submitted.
There was an interesting development. A colleague called and asked me for advice on how to insert 4 billion rows in a table with a simple structure.
create table t1 (
id tinyint not null
);
Very simple. No primary key, no indexes. It is needed to perform some specific tests.
Actually, not 4 billion, but 2^32 records are needed, i.e. 4,294,967,296.
The classical method used in these cases is doubling the table contents:

insert into t1 values (1),(1),(1),(1),(1),(1),(1),(1);
insert into t1 select * from t1;
insert into t1 select * from t1; # and so on
My solution was similar to the one from my quiz.
CREATE VIEW `v4` AS
select NULL
union all select NULL
union all select NULL
union all select NULL;

CREATE VIEW v1024 AS
select null from v4 a, v4 b, v4 c, v4 d, v4 e;

INSERT INTO t1 select 1 from v1024 a, v1024 b, v1024 c, v4 ;
This one is faster than the doubling method, but it still requires from 40 to 65 minutes, depending on how fast is your server.
So, the challenge, for which we will give away 1 MySQL T-shirt to the winner, is as following:
  • Generate 2^32 records for table t1;
  • no limits to the length of code to use;
  • you can use stored routines, temporary tables, views, events, whatever makes the insertion fast;
  • the method must be portable across operating systems. If it is not portable, a Unix-only method may be accepted if it is exceptionally faster than SQL-only solutions;
  • methods relying on external applications cannot be accepted;
  • If an programming language is needed, for compatibility with the test suite we can only accept Bash shell or Perl scripts;
  • If you devise a fast method to insert data using MySQL Proxy, a Lua script can be accepted.
  • what matters is the final insertion speed and ease of use.
  • If a method uses an external script, its speed must be more than 20% faster than the fastest method using only SQL.
  • The speed will be calculated on my server, using MySQL 5.1.23.

Solutions so far

  • Dpin. 20 minutes for a portable solution is very good.
  • Jedy. Very nice, but not that fast. 32 minutes.
  • Todd. Brilliant solution (10 minutes for 4 billion rows!), but really impractical. We need something that works for any engine. This one is a dirty trick that is fun to use once, but in the long run it won't stand.