Bug #75876 Un-necessary RPM dependency will prevent major upgrade
Submitted: 12 Feb 2015 12:22 Modified: 16 Feb 2015 14:54
Reporter: Jörg Brühe (OCA) Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server: Packaging Severity:S3 (Non-critical)
Version:5.5 and up OS:Linux
Assigned to: CPU Architecture:Any
Tags: common, libs, requires, rpm

[12 Feb 2015 12:22] Jörg Brühe
Description:
The new RPMs "mysql-*" specifically targeted at RedHat, Fedora, SuSE, ... have split off the "charset" and "errmsg.sys" files into a separate "common" subpackage.
Then, there is a "requires" in both the "server" and the "libs" subpackage that forces that "common" subpackage of exactly the same version to be installed.

In "libs", this "requires" is not needed, and if it were needed it were harmful:

1) "libs" contains only "libmysqlclient.so.18.0.0" (both MySQL 5.5 and 5.6), and in this library there is no code accessing any of the files in "common". (I checked using "strings -a".)

2) The equivalent to "mysql-libs" among the old RPMs "MySQL-*" is "MySQL-shared", and this package neither contains those files nor does it "require" another subpackage that would provide them.

3) Assume some future version, say MySQL 5.8, will change the ABI of libmysqlclient, so it will bring "libmysqlclient.so.19.0.0". Then, applications built against MySQL 5.5 or 5.6 will need to get the current library via some "mysql-libs-compat" RPM. If the current dependency were correct, this RPM would need to have the current files of the "common" subpackage installed, but "mysql-libs-5.8" would require the new ones: file conflict.

Yes, I am aware that this error may have been introduced by the original RedHat spec file which had those files of your "common" directly in their "libs" subpackage, which made upgrading the server really difficult (caused a file conflict). IMO, that design desision was wrong from the start.

How to repeat:
Code inspection, and/or
rpm -q --requires mysql-libs

Also, if that requirement were correct, how would your "mysql-libs-compat" RPMs work, which do not have it?

Suggested fix:
Remove the following lines from the "%package libs" section:

Requires:       mysql-commercial-common%{?_isa} = %{version}-%{release}
Requires:       mysql-community-common%{?_isa} = %{version}-%{release}
[13 Feb 2015 8:40] Terje Røsten
Hi Jörg!

Let try me try to explain the background for this setup.

a) when using libmysqlclient.so.* it needs files from common
package to produce correct error msgs.

b) mysql-libs package in distros ships libmysqlclient.so.X.Y.Z,
/usr/share/mysql/* and /etc/my.cnf

c) error msg file is append only, all previous error are intact
from previous releases, this means older clients and libs can use
newer error msg files.

d) libs-compat package are built together with server and libs,
this means libs-compat will get same version as server, however actual 
version of libs in libs-compat are different. A libs-compat package 
will only work with specific server package version.
[13 Feb 2015 10:01] Jörg Brühe
Hi Terje!

Thanks for the reply, but I'm not yet convinced:

a) Using "strings -a" on the "libmysqlclient.so", I do not see the "errmsg.sys" file name, so I don't see any indication it is opened. (Admitted, I haven't yet set up a test environment.)
Also, how does the old "MySQL-shared" RPM work? Neither does it contain "errmsg.sys", nor does it require some other subpackage that would provide it.

b) I'm aware of that RedHat "mysql-libs" RPM, and of the difficulties it makes when I want to install a newer MySQL server (say MySQL 5.5 on RedHat 6). IMO, their design is wrong.
Look at a SuSE "libmysqlclient" RPM, this is the way it should be done IMNSHO.

c) I'm aware of "append-only". By that argument, "mysql-libs" should "require" the "mysql-common" of *at least* the current ("libs") version, not of *exactly* that version.

d) I don't think that "libs-compat" will only *work* with that server version. It will *require* the "libs" of that version to be installed, which then requires the "common" package of that version. *If* the "libmysqlclient.so.OLD" (from "libs-compat") really needs "errmsg.sys", that "requires" should be to "mysql-common" - the contents of "libs" is not needed.

But again: How does the old "MySQL-shared-compat" work, which neither contains nor requires any "errmsg.sys" file?
And similar: How do the RPMs distributed by SuSE work? Their "libmysqlclient_r15" only contains "/usr/lib64/libmysqlclient_r.so.15.0.0" (and some symlinks to it), no "errmsg.sys" or a "requires" that would bring it.

I would like to test this, by running some application on a machine that does not have "errmsg.sys". Under which circumstances would "libmysqlclient.so" or some other client program need "errmsg.sys"?
[13 Feb 2015 15:31] Jörg Brühe
The test script

Attachment: test-75876.sh (application/x-shellscript, text), 1.29 KiB.

[13 Feb 2015 15:32] Jörg Brühe
Test log with packages "client", "libs", "common"

Attachment: bug-75876-run-1.log (text/x-log), 4.17 KiB.

[13 Feb 2015 15:33] Jörg Brühe
Test log with "client" + "libs", but "common" erased forcefully

Attachment: bug-75876-run-2.log (text/x-log), 2.30 KiB.

[13 Feb 2015 15:33] Jörg Brühe
Test log with just "client", both "libs" and "common" erased using "--force"

Attachment: bug-75876-run-3.log (text/x-log), 2.26 KiB.

[13 Feb 2015 15:35] Jörg Brühe
I have run a small test, using "mysql" with a remote server and issuing commands that will produce error messages:
It does not matter whether the "common" RPM with its "errmsg.sys" is installed or not, the error messages are produced as expected.

Similar, the "libs" RPM is also not needed, because the "mysql" binary does not use a shared "libmysqlclient.so" (is linked statically).

The test script and the three logs are already attached to this bug.
[16 Feb 2015 11:57] Hartmut Holzgraefe
> a) when using libmysqlclient.so.* it needs files from common
> package to produce correct error msgs.

The server error codes are resolved by the server side and transferred in textual form to the client (in addition to the numeric code), as is e.g. visible in strace output:

In the trace below '3' is the clients socket connection handle:

  socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
  [...]
  connect(3, {sa_family=AF_INET, sin_port=htons(3306), 
    sin_addr=inet_addr("127.0.0.1")}, 16) = 0

and when sending an invalid query to that socket the error message is received on that socked right away:

  write(3, "\t\0\0\0\3select x", 13) = 13
  read(3, "+\0\0\1\377\36\4#42S22Unknown column 'x' "..., 16384) = 47

Client side error messages on the other hand are hard coded 
in libmysql/errmsg.c without a translation mechanism:

  const char *client_errors[]=
  {
    "Unknown MySQL error",
    "Can't create UNIX socket (%d)",
  [...]
  };

What *does* have a dependency on errmsg.sys is the embedded server
library (libmysqld). But not the regular client library (libmysqlclient)
[16 Feb 2015 13:53] Terje Røsten
Hi guys,

I think charsets are needed by libmysqlclient, while errmsg are not.

However, for repository to be simple to operate for users a dep between libs and common package seems to be the best way.

Sorry about the confusion.
[16 Feb 2015 14:54] Jörg Brühe
Result of discussion:

"libs" does indeed need "common", because it may access the charset info.

"libs-compat" contains old libraries, so it will also need "common".
I do not see a need for "libs", though:
In the spec for "libs-compat", there could be a "Requires: common".

My initial understanding was wrong, so I set this to "Not a bug". Sorry about the confusion.