94

I'm trying to create a simple structure only dump of my database. Using mysqldump gives me a result like:

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

DROP TABLE IF EXISTS `foo`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;

No matter what I try, I just can't seem to get rid of those comments.

I'm currently using: mysqldump -p -d --add-drop-table --skip-tz-utc --skip-set-charset -h 127.0.0.1 -u foo bar --result-file=dumpfile.sql

Edit: I do however wish to retain other comments, such as -- MySQL dump 10.13 Distrib 5.1.41, for Win32 (ia32)

etheros
  • 2,733
  • 2
  • 24
  • 25
  • 2
    I wonder why Oracle did not add such important options to mysqdump? – Handsome Nerd Jun 29 '15 at 11:20
  • Not a direct answer - but I have ditched straight mysqldump entirely for [mk-parallel-dump](http://www.maatkit.org/doc/mk-parallel-dump.html) - it's faster (spawns multiple processes) and depending on what you are going to do with the dump output, more flexible as it effectively encapsulates mysqldump and 'select into outfile' syntax together. – zznate Dec 16 '09 at 18:20

15 Answers15

188

WHOA! These aren't really comments even though they look that way. They are conditional-execution tokens.

Take this line:

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;

If the version of mySQL is 4.00.14 or higher, then the MySQL server will run this statement.

This magic comment syntax is documented in the Comment Syntax section of the manual.

You probably don't want to get rid of this stuff.

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
O. Jones
  • 103,626
  • 17
  • 118
  • 172
  • 2
    Another question that specifically asks about comments in MySQL being treated as executable SQL (just posted by me): http://stackoverflow.com/questions/25614919/where-is-it-documented-that-some-comments-in-a-sql-script-executed-by-mysql-usi – Dan Nissenbaum Sep 02 '14 at 04:20
  • 1
    There are some cases when removing comments can help. i.e. http://bugs.mysql.com/bug.php?id=48972 when --insert-ignore doesn't work as expected because of them – varela Feb 11 '15 at 21:37
  • +1 I never knew that. I thought they were just commands that mysql dump was running as it exported. Very enlightening answer. – Captain Hypertext Jul 19 '15 at 21:45
  • 1
    Suppose that should mean there should be compatibility expected options, that specify whether you expect to run the sql on older mysql versions, and if not, on need to wrap it in a conditional comment. – CMCDragonkai Jul 12 '17 at 11:35
42

I know this is an ancient question, but here is an answer at least. I also couldn't find a flag in mysqldump to remove the conditional comments, or indeed a better option to set a minimum mysql version for these comments to appear. If you just want to nuke them all, you can do so using grep or sed (sed leaves blank lines, grep does not):

mysqldump ... | grep -v '^\/\*![0-9]\{5\}.*\/;$'
mysqldump ... | sed -e 's/^\/\*![0-9]\{5\}.*\/;$//g'

To answer my own wish of conditionally removing comments dependent on mysql version, use one of these (removes any comments for anything < mysql5):

mysqldump ... | grep -v '^\/\*![0-4][0-9]\{4\}.*\/;$'
mysqldump ... | sed -e 's/^\/\*![0-4][0-9]\{4\}.*\/;$//g'
Tom Hennigan
  • 1,082
  • 1
  • 9
  • 17
  • 1
    For rsnapshot backups it is useful to get rid of the last line, so a database, that didn't change results in the same file: `mysqldump ... | grep -v '^-- Dump completed on .*$'` – rubo77 Nov 09 '15 at 07:53
  • yeah but the problem is you may lose the `DROP DATABASE IF EXISTS ` OR `IGNORING YOUR CURRENT SESSION VARIABLES `. Unless you know what your doing: Don't remove them ESPECIALLY WHEN MIGRATING BETWEEN ENVIRONMENTS/HOSTS. as the resulted output may not be as expected, for any number of reasons. They were put there for your protection. but if you don't want to put your seatbelt on that is your choice. – JayRizzo May 31 '17 at 00:43
  • 2
    @rubo77 You could use this mysql dump parameter as well: `--skip-dump-date` – dehart Oct 08 '19 at 12:16
37

Try --skip-comments ?

Thanks

Edit:

I see .. Try this

--skip-add-drop-table --skip-add-locks --skip-disable-keys --skip-set-charset

Play around to remove some of the options till you get the desired result, basically this is same as --compact without --skip-comments

--skip-comments removes the comments relating to version and stuff ..

Mahesh Velaga
  • 21,633
  • 5
  • 37
  • 59
  • 6
    Unfortunately this removes all the comments I do want, leaving all of those I don't intact. – etheros Dec 16 '09 at 17:59
  • @etheros I concur, but we should elaborate. My use-case relates to source-controlled structural data. I don't want any non-essential chatter for every table. I like the `SET NAMES` call that `--skip-set-charset`, as suggested in this answer, removes; it happens only once at the beginning of the dump file, and could affect data restoration in a material way. I do like `--skip-add-locks --skip-disable-keys` for my use-case. But some of the conditional comments, such as `/*!40101 SET character_set_client = @saved_cs_client */;` and `/*!40101 SET character_set_client = utf8 */`... useful, or not? – Ben Johnson Feb 20 '18 at 01:41
  • 1
    @BenJohnson No they are not. `character_set_client` cannot be set in 5.6 due to a bug or something, so when you are mysqldumping for example `utf8mb4` data, you get these conditional comments where you don't want them. – Slava May 01 '18 at 08:58
22

Have you tried the shortcut option --compact?

Information here.

Corey Ballou
  • 42,389
  • 8
  • 62
  • 75
  • 2
    I did, however it disables other comments I *do* want, such as `-- MySQL dump 10.13 Distrib 5.1.41, for Win32 (ia32)`. – etheros Dec 16 '09 at 17:57
13

Technically the lines you are trying to get rid of are not comments. They temporarily modify some variables at the beginning, and then reset them to the previous value at the end.

They're not very useful (but they're also harmless) in your case, since you're using --no-data, but I thought it worth mentioning that the lines do serve a purpose, and are not just comments.

Ike Walker
  • 64,401
  • 14
  • 110
  • 109
4

Those are not comments, the execution of that part of the scripts depends on the version of your mysql.

You can delete "the comment part", like

/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */

to

SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0

making the script more "comfortable" for reading.

If you try to run a "comfortable" script in a version newer than the specified in the "comment", you will get an error.

Mark E. Haase
  • 25,965
  • 11
  • 66
  • 72
Gustavo
  • 49
  • 1
  • 2
    How can we "delete the comment part"? Is there a dump option for this? I don't want to go through a couple gig file by hand. – mpen May 20 '15 at 15:37
  • Actually it should be: If you try to run a "comfortable" script in a version **older** than the specified in the "comment", you will get an error. – Daniel Sep 05 '19 at 12:54
2

Use --dump-date=FALSE

Does exactly what OP asks for. (not exactly, I see)

Source: mysqldump option summary

Edit: Just after a minute I realized, this is what me was looking for not the OP, but leaving here... in hope someone can use it: This date line which ruins source control, because it always a change...

Eduardo Cuomo
  • 17,828
  • 6
  • 117
  • 94
g.pickardou
  • 32,346
  • 36
  • 123
  • 268
2

It's really important to keep the conditional-execution comments. But if you absolutely know that the MySQL version that will load the dump is greater or equal to the one that creates it, you can remove the "comment" part with this:

sed -r  s'#/\*![0-9]{5} ?([^*]*)\*/#\1#'g

It will convert lines such as

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;

to

SET SQL_MODE=@OLD_SQL_MODE ;

Because this line must run on any MySQL >= 4.1.1

Note that this will not remove multi-line conditional-execution comments, such as when dumping a trigger.

Since it's impossible to predict the future, it's better to store the dump with the comments on, and only remove them when you want to visualize it.

mysqldump ... > dump.sql
cat dump.sql | sed -E  s'#/\*![0-9]{5} ?([^*]*)\*/#\1#'g > dump.no-comments.sql
Daniel
  • 2,869
  • 4
  • 26
  • 28
1

If you've stumbled up on this answer trying to include your structure.sql file in git/github, you can strip out auto-increment with the following code right after you rake db:structure:dump

# Remove beginning auto increments to prevent merge conflicts
filename = 'db/structure.sql'
File.atomic_write(filename) do |output|
  File.open(filename, 'rb').each do |input|
    output.write(input.gsub(/\s+AUTO_INCREMENT=\d+\s+/, ' '))
  end
end
jwg2s
  • 806
  • 1
  • 12
  • 25
  • 1
    What's with all the downvotes on the "strip the lines with a regexp" answers? These are totally valid. This one in particular is entirely applicable to my situation. +1's for all of you. – plainjimbo Aug 21 '14 at 18:49
  • Better than `gsub`'ing though, how can we just make sure our local DB is equal to that of our collaborators. Then you won't have to do all this.. – Trip Apr 05 '22 at 16:34
0

Probably running a regex on it to remove lines that contain 40014 or 40111 etc.

MindStalker
  • 14,629
  • 3
  • 26
  • 19
0

Since you are on Windows, if no-one finds a better solution then you could use a Python script instead:

import re, sys
sql = sys.stdin.read()
regex = re.compile(r'/\*![^\n]* \*/;\n', re.M)
print regex.sub('', sql)

Usage from command line:

python program.py < your.sql > output.sql

It removes all lines like this:

/*!....... */;
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
0

I made this script to normalize the dump, including removing conditional comments: https://github.com/luissquall/dbdump.

You just have to:

npm install -g @luissquall/dbdump

# Redirect output to a file
dbdump -u user -p -d database > struct.sql
luissquall
  • 1,740
  • 19
  • 14
0

I used the following multiline Perl regexp to remove these lines from my dump file:

perl -0pi -e 's/\/\*\!\d+(.*?)\*\//\1/gms' dump.sql

I found other sed solutions not sufficient in cases where my trigger procedures spanned multiple lines.

dansimau
  • 1,155
  • 1
  • 8
  • 11
-1

I dont know if it is what are you looking for, i simply wanted to get rid of all the mysql comments stuff to be able to use a syntax highlighter, i used a simple regex and replace all with the following "/\*![0-9]{5}|\*/" and voila! nice colors in the code ;)

ITomas
  • 809
  • 9
  • 15
-1

As @Ollie and a few others pointed out, these are are conditional-execution tokens written in comment style but served a purpose. Without them, you may run into issues of recreating tables with heavily enforced foreign key constraint. For instance, table A has FK for table B and thus table A cannot be created until table B do and so on so forth. Without disabling the key checks, you may never be able to recreate them depending how your table order is fined.

Devy
  • 9,655
  • 8
  • 61
  • 59