Bug #67576 Misleading messages at startup time
Submitted: 13 Nov 2012 0:48 Modified: 16 Jul 2013 16:36
Reporter: Tianyin Xu Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Errors Severity:S3 (Non-critical)
Version:mysql-5.5.28 OS:Linux (Ubuntu-12.04)
Assigned to: CPU Architecture:Any
Tags: configuration, Contribution, lc-messages-dir, messagefile

[13 Nov 2012 0:48] Tianyin Xu
Description:
Hi, I'm new to MySQL, and I installed mysql-5.5.28 on a Ubuntu-12.04 machine.

====================Symptom==================== 

After starting mysqld, the server shutdown with the following error log:
 
121112 15:58:38 [ERROR] Can't find messagefile '/usr/local/mysql/data/errmsg.sys'

From the message, I thought it's because the messagefile does not exist. So I created the file,

#touch /usr/local/mysql/data/errmsg.sys

However, this time, the server still failed to start with different error logs as follows:

121112 15:58:07 [ERROR] An old style --language value with language specific part detected: /usr/local/mysql/data/
121112 15:58:07 [ERROR] Use --lc-messages-dir without language specific part instead.
121112 15:58:07 [ERROR] Can't read from messagefile '/usr/local/mysql/data/errmsg.sys'

I was really confused because the “messagefile” do exist with the proper permission.

#ll 
/usr/local/mysql/data/errmsg.sys
-rw-r--r-- 1 mysql mysql 0 Nov 12 12:35 /usr/local/mysql/data/errmsg.sys

Also, I don't understand the other two error logs at all:

“[ERROR] … with language specific part detected: /usr/local/mysql/data/
”

What does it mean? What is the language specific part?

====================Root Cause and Suggestion==================== 

After asking around on the mailing list, and looking at the code, I understand the system behavior. This is because of the following misconfiguration which is automatically generated after installation:

#my.cnf
lc_messages_dir = /usr/local/mysql/data     #/usr/local/mysql/data is $DATADIR

Basically, mysqld first tries to look for the file under 

lc_messages_dir + language + errmsg.sys (in my case, /usr/local/mysql/data/english/errmsg.sys)

If it cannot find the file, it assume that users set “lc_messages_dir” to “lc_messages_dir + language”, that's why the message is “[ERROR] … with language specific part detected”. 

If neither of the two paths exists, it prints out the message:

“Can't find messagefile '/usr/local/mysql/data/errmsg.sys'”

I have to say the log message is really misleading, and does not pinpoint the real problem. 

Since the related function is “Read text from packed textfile in language-directory.” (according to the comments), why not explicitly print out the root cause, i.e., the value of “lc_messages_dir” is wrong instead of “cannot find the messagefile”. After all, there's no “messagefile” configuration directive in my.cnf.

Also, I suggest to put the two print statements after successfully read from the errmsg.sys, which makes more sense, i.e., mysqld does find a valid errmsg.sys from the old-style path.

====================Related Code====================

/* sql/derror.cc */

116   if ((file= mysql_file_open(key_file_ERRMSG,
117                              fn_format(name, file_name, lang_path, "", 4),
118                              O_RDONLY | O_SHARE | O_BINARY,
119                              MYF(0))) < 0)
120   {
121     /*
122       Trying pre-5.4 sematics of the --language parameter.
123       It included the language-specific part, e.g.:
124       
125       --language=/path/to/english/
126     */
127     if ((file= mysql_file_open(key_file_ERRMSG,
128                                fn_format(name, file_name, lc_messages_dir, "", 4),
129                                O_RDONLY | O_SHARE | O_BINARY,
130                                MYF(0))) < 0)
131       goto err;
132     sql_print_error("An old style --language value with language specific part detected: %s", lc_messages_dir);
133     sql_print_error("Use --lc-messages-dir without language specific part instead.");
134   }
…...
…...
185 err:
186   sql_print_error((funktpos == 2) ? "Not enough memory for messagefile '%s'" :
187                   ((funktpos == 1) ? "Can't read from messagefile '%s'" :
188                    "Can't find messagefile '%s'"), name);
189   if (file != FERR)
190     (void) mysql_file_close(file, MYF(MY_WME));
191   DBUG_RETURN(1);

How to repeat:
In my.cnf, set the following misconfiguration:

lc_messages_dir = $DATADIR

You can follow the "Symptom" subsection (which describes the process) in the "Description" Section.

Suggested fix:
In sql/derror.cc:

131a132,133
>     sql_print_error("An old style --language value with language specific part detected: %s", lc_messages_dir);
>     sql_print_error("Use --lc-messages-dir without language specific part instead.");
142,144d143
<   sql_print_error("An old style --language value with language specific part detected: %s", lc_messages_dir);
<   sql_print_error("Use --lc-messages-dir without language specific part instead.");
<   
189c188
<                    "Can't find messagefile '%s'! Please check the 'lc-messages-dir' configuration directive."), name);
---
>                    "Can't find messagefile '%s'"), name);
[13 Nov 2012 3:20] Tianyin Xu
Osh, the patch attached in the previous email is not correct. Check out this new one!

--- ../mysql-5.5.28_org/mysql-5.5.28/sql/derror.cc      2012-08-29 01:50:46.000000000 -0700
+++ sql/derror.cc       2012-11-12 19:14:14.075581201 -0800
@@ -108,6 +108,7 @@
   uchar *buff;
   uchar head[32],*pos;
   DBUG_ENTER("read_texts");
+  bool ostyle = false;
 
   LINT_INIT(buff);
   funktpos=0;
@@ -129,8 +130,8 @@
                                O_RDONLY | O_SHARE | O_BINARY,
                                MYF(0))) < 0)
       goto err;
-    sql_print_error("An old style --language value with language specific part detected: %s", lc_messages_dir);
-    sql_print_error("Use --lc-messages-dir without language specific part instead.");
+
+      ostyle = true;
   }   
 
   funktpos=1;
@@ -140,6 +141,11 @@
       head[2] != 2 || head[3] != 1)
     goto err; /* purecov: inspected */
   textcount=head[4];
+  
+  if(ostyle) {
+      sql_print_error("An old style --language value with language specific part detected: %s", lc_messages_dir);
+      sql_print_error("Use --lc-messages-dir without language specific part instead.");
+  }
 
   error_message_charset_info= system_charset_info;
   length=uint2korr(head+6); count=uint2korr(head+8);
@@ -185,7 +191,7 @@
 err:
   sql_print_error((funktpos == 2) ? "Not enough memory for messagefile '%s'" :
                   ((funktpos == 1) ? "Can't read from messagefile '%s'" :
-                   "Can't find messagefile '%s'"), name);
+                   "Can't find messagefile '%s'! Please check the 'lc-messages-dir' configuration directive."), name);
   if (file != FERR)
     (void) mysql_file_close(file, MYF(MY_WME));
   DBUG_RETURN(1);
[13 Nov 2012 3:27] Tianyin Xu
patch

Attachment: lc.patch (text/x-patch), 1.55 KiB.

[13 Nov 2012 17:40] Sveta Smirnova
Thank you for taking the time to write to us, but this is not a bug. Please double-check the documentation available at http://dev.mysql.com/doc/ and the instructions on
how to report a bug at http://bugs.mysql.com/how-to-report.php

You should not create empty errmsg.sys file, but point to proper one from your installation. Most likely --lc-messages-dir=mysql_installation_path/share
[13 Nov 2012 18:12] Tianyin Xu
Hi, Sveta,

Thanks for your reply.

It's not a bug (won't crash the system), but a bad message which misleads users. 

What I mainly proposed is to improve the quality of the log message 
"Can't find messagefile XXX" by explicitly telling which configuration directive is wrong (fortunately, in this case, we can). So that users can immediately know the problem. This can save a lot of time for users.

I think it does make sense.
[15 Nov 2012 19:47] Sveta Smirnova
Thank you for the feedback.

Got your point: verified as described.
[15 Nov 2012 21:57] Tianyin Xu
Thanks a lot, Sveta!

T
[16 Jul 2013 16:36] Paul DuBois
Noted in 5.7.2 changelog.

If the server could not find the errmsg.sys file at startup, the
resulting error message did not indicate which configuration
parameter to check.