tags:

views:

342

answers:

2

I dumped the data from a database using the MySQL Admin Migration toolkit. One of the tables has over 5 million rows. When I try to load the generated data file I get out of memory issues. Is there a way to force commit after X number of rows. The script generate by the migration toolkit is shown below.

INSERT INTO mytable (`col1`, `col1`)

VALUES (823, 187.25), (823, 187.25), (823, 187.25), (823, 187.25), (823, 187.25), (823, 187.25), (823, 187.25), (823, 187.25), (823, 187.25), (823, 187.25), (823, 187.25), (823, 187.25), (823, 187.25), (823, 187.25), (823, 187.25),

+2  A: 

Yes. This big INSERT INTO statement is essentially a script. Take an editor to it; every few hundred lines, insert a line that says COMMIT, and then start a new INSERT...VALUES statement.

For extra credit, you can write a simple script to rewrite the original SQL statement into several transactions (as stated above) programmatically. You don't want to be doing this by hand repeatedly.

There's no outside setting you can activate so that you can submit this script in its entirety and have auto-commits happening at regular intervals without changing the script.

Increasing log file space may raise the limit but I wouldn't count on it. Face it: The DB was simply not built to process statements several thousands of lines in length.

What I'd probably do is do multiple commits but push this stuff to a temporary table or with a "temporary" flag; and then run one or a small number of operations to make these changes permanent. If that goes wrong, you can still retry or delete your temporary records.

Carl Smotricz
Would you really want to commit multiple times though? If something fails later on, you'd end up with inconsistent data.
Kevin Peno
It's not a question of wanting to. There is to the best of my knowledge no other way. Raising your commit space to many gigabytes may work in Oracle but it's quite possible it simply doesn't fly in MySQL. It's a toy database, after all.
Carl Smotricz
You are right, but if the ability to rollback is important, you should reformat the inserts anyway OR, at least temporarily, increase the INNODB buffer size. The only limitations I am aware of in MySQL for buffer size is system memory, but I could be wrong
Kevin Peno
There's also a limit for InnoDB log files to 4 GB. That's fairly generous, in this case I guess the problem may be more with pushing an X-L arge SQL statement through String buffering in Java.
Carl Smotricz
What I'd probably do is do multiple commits but push this stuff to a temporary table or with a "temporary" flag; and then run one or a small number of operations to make these changes permanent. If that goes wrong, you can still retry or delete your temporary records.
Carl Smotricz
I would write a simple program to do this, not use an editor. Would you really want to do this manually on a source file with five million lines in it?
Robert Harvey
I like the temp table suggestion. Then you could push it all there and perform a more comfortable transaction later (removing the need for a transaction at all during the first insert) Add this to your answer and you have a +1
Kevin Peno
@Robert Harvey: Doing this programmatically is the "advanced" option, that'll cost more ;)
Carl Smotricz
@Kevin Peno: I'm such a whore for points, I did exactly what you asked! :) But I don't know it's possible to insert -without- transactions; your only choice is whether to make them explicit or just let the dang thing autocommit after every statement.
Carl Smotricz
Right, I actually meant allowing autocommit to just handle it.
Kevin Peno
Ah, OK then. (15 chars)
Carl Smotricz
+3  A: 

Ask your DBA to Increase the innodb_log_file_size to 256MB from the default 5M. It gives a good performance boost for write-intensive workloads as well. Be careful, as when changing this setting you need to remove the old logfiles before restarting the daemon. It should remove the need for "auto-commit every X rows" altogether.

ggiroux
+1, if this really works.
Robert Harvey
Assuming the data itself does not breach the 4GB INNODB log limit (as Carl mentions), this is the answer I would have suggested.
Kevin Peno