-
Notifications
You must be signed in to change notification settings - Fork 7.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix GH-7932: MariaDB version prefix not always stripped #7963
Conversation
For consistency with `mysqlnd_conn_data#get_server_version`, we strip the MariaDB version prefix also in `mysqlnd_command#handshake`.
I understand the confusion, however it works exactly how it is supposed to now (probably).
If we want to fix this, we should remove the hack that we currently have in PHP. Let MariaDB 10 claim to be version 5.5.5 if they want. This will probably result in bug reports from users claiming that our hacky logic makes more sense. So as a compromise, I would leave it as it is now. The string returned by |
But under the hood, this server claims to be 5.5.5-10.5.13-MariaDB. In my opinion, that version mess (it's not only about the compatibility prefix) will bite many clients in the future, but somehow we have to deal with this. I'm okay with leaving everything as is, but the inconsistency could be confusing for users. Maybe we should introduce an INI setting for this, but that could cause even more confusion. At the very least we should properly document how mysqlnd handles this. |
As long as we provide the |
Okay, then let's make that a doc issue. Thank you! |
@kamil-tekiela links like https://jira.mariadb.org/browse/MDEV-9565?page=com.googlecode.jira-suite-utilities%3Atransitions-summary-tabpanel https://stackoverflow.com/questions/56601304/what-does-the-first-part-of-the-mariadb-version-string-mean clearly show this is a pure * transport * hack and it should never reach the end user. Is this enought proof to reopen or can you please connect wit someone from MariaDB to reconfirm? The |
You've mentioned me in a previous (now edited-away) version of the above comment, so I'm here to reconfirm. Yes, it is a pure transport hack. MySQL replication used to decide whether the server is using a new or old replication protocol by looking at the first byte of the version. Any conforming client is expected to strip this prefix away. |
I just discovered that my server broke with the following command about an hour and change ago: $version = mysqli_get_server_info($db); I've seen at least one other thread about this. I can see the automatic update from 8.0.15 to 8.0.16 via yum history info 120. Live Linux server and the MySQL version has now been stripped. This code had been working fine for the past several years minimally. I'm not seeing any direct commitment to change the string output though obviously someone somewhere did. I've been relying on it to avoid another pointless SQL query to the server to ensure that various versions of the software (e.g. PHP, MariaDB) are installed for day-to-day maintenance as well as when I have to do server migrations manually as my host only totally sucks when it comes to migrations and I need to ensure that the various versions of software are proper. Could someone please check and make sure someone didn't go crying to dad in another thread because mom wouldn't do so-and-so? I don't need things breaking because someone else doesn't know how to work with string functions. |
@jabcreations Every bug fix can potentially break someone else's workflow. Mandatory XKCD reference. |
@jabcreations, you're likely referring to commit 5fc0db9. That fix has been done to work around the MariaDB versioning issues. |
This was very old code though I test things such as changing the numbers around to ensure that it would trigger if things changed. This was working until about 5AM earlier this morning when the server updated from 8.0.15 to 8.0.16:
I have a log viewer that I use with MariaDB and this command apparently does not create an SQL query so it has a slight performance benefit over using SELECT VERSION();. I don't mind horribly using something else (ideally, not adding a database query albeit only for myself as the Administrator) though we're programmers dealing with strings all of the time so I'd like to avoid having to have the concerns of questioning if I'll have to start rewriting code years later because of a literal minor update like this. |
please post here the actual/expected result of |
Comparing a string to a float seems to be a very naive and potentially invalid behaviour. Are you sure this piece of code is correct? Maybe it should be using You mentioned something about using string functions. Can you demonstrate how you are using this function with any of the string functions? |
The code worked fine then and as I said I had tested it against static copies with different versions. 5.5.5-10.5.4-MariaDB-log mvorisek I recommend looking in to PHP functions such as explode, substr and substr_count. |
@jabcreations Why do you expect the version with the prefix to be returned by this function? I am still unclear on what you think the regression is or why you think the prefix should be there. The actual MariaDB version is 10.5.4. Anyway, if you want to know the version number, you are using the wrong function. To clarify why your code is currently broken. |
Apparently, that code worked by sheer luck as of PHP 8.0.0, where that comparison behavior has changed. You're likely better off using |
I'm not sure why the mysqlnd should do additional procedures for mariadb, and cause incompatible results. There are lots of databases trying to use mysql-like protocol, like percona and tidb,and lots of cloud databases like amazon aurora, TDSQL-C and more. |
In the context of this bug, only the prefix in the version string is stripped out. The version number has already been parsed ignoring the prefix. The prefix was added as a technical workaround by MariaDB and if you follow the conversation, to make it compatible with MySQL, the prefix must be stripped
That has always been the case. Mysqli returns the information that is provided by the server. MariaDB returns information identifying itself in a MySQL compatible way (if we ignore that MySQL has a single-digit version and MariaDB double-digit).
The mysqli extension is meant to be used to connect to MySQL-like databases. While it's true that MySQL and MariaDB are diverging more and more, they are still compatible enough to not require any special treatment. This small change that was done to fix this bug, isn't breaking compatibility. It's only stripping away technical information that should not be exposed to PHP code anyway. If you really need to have that prefix, please go ahead and prepend As an aside, I would really be interested to know what code relied on this prefix that seems to have stopped working now. It seems very odd to me that it would be used rather than the |
It needs to be clear that the MariaDB side announces to the application side that its database has a certain compatibility with MySQL 5.5.5 through MariaDB/server@c50ee6c#diff-5b45fa673c88c06a9651c7906364f592, and the application side can process its related processes according to MySQL 5.5.5. The version number actively reported by MariaDB should be respected. If they only want to use this version number during replication, MariaDB or the application should actively distinguish between replication requests and ordinary requests, instead of directly hacking them. Stepping back 10,000 steps, the current modification method actually removes this compatibility layer and causes BC on the application side. Such modification should at least be done in the major version like PHP 8.2, otherwise it will cause incompatibility between the old minor version and the new minor version. My current version of the software is not GA, so I can complete compatibility through troubleshooting and modification. I also do not deny that the method of directly comparing the size or intercepting the first position of the version number is inappropriate, but the PHP ecosystem determines that most of the software is not used by developers, and it is very difficult for users to troubleshoot and diagnose such problems. so upstream should consider the issue of forward compatibility when making changes in the minor version number. If the software is already GA and claims that the current version supports PHP 8.0, then this modification will directly break the downstream commitment to end users, which will cause application developers to lose trust in users, and may cause application developers to violate licenses The protocol was even sued, hoping that the upstream would consider the downstream instead of modifying it arbitrarily when making incompatible changes to the minor version. |
@kamil-tekiela Thanks for your reply!
For example, this is a demo working properly in PHP 8.1.2 and 10.1.37-MariaDB: error_reporting(E_ALL);
// connect the mysql server
$conn = new mysqli();
$conn->real_connect('127.0.0.1','testdb','testdb','testdb', null, null, MYSQLI_CLIENT_COMPRESS);
$conn->set_charset('utf8');
$conn->query("SET sql_mode=''");
$conn->query("SET character_set_client=binary");
// trying to create table
// mysql version 5.7 and later can use larger index key prefixes
var_dump($conn->server_info);
$keylimit = version_compare($conn->server_info, '5.6', '>') ? '' : '(180)';
$sql = <<<EOT
CREATE TABLE `mail` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`mail` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `mail` (`mail`$keylimit)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
EOT;
if(!$conn->query($sql)) {
var_dump($conn->error);
} else {
echo 'create table success';
} varchar(255) is commonly used and will work in older databases. But when they try to add full UTF-8 support (like emoji), they need to change the whold database to utf8mb4, then the 767 bytes max key length is not enough anymore so such workarounds may be used to solve this problem. And it do works for many years. But when the users update the PHP from 8.1.2 to 8.1.3, it will not work anymore (10.1.37-MariaDB):
And MySQL will continue to publish new versions in the future and maybe MySQL 10 will be released someday. What can we do at that time? |
Ok, I understand, but in that case, you are talking about an entirely different problem. The dummy prefix wasn't meant to be used like you did in the code above. It was only meant to tell the replication software that it's not talking to MySQL 1 database. All MariaDB 10 versions have that prefix that should be used only in replication and stripped anywhere else. If you want to write code that can be interoperable on both databases and have feature detection, you need to build some rules. As I said, both databases are diverging. The features and even SQL syntax differs between them. You might only rarely encounter this but as shown in the example, it is a real problem. It won't help you if we retain the MariaDB replication prefix as that wasn't actually telling you anything useful about the capabilities of the server. You would have to check for PHP-SRC can't accommodate your request as the bug has been fixed correctly. The prefix is gone now and the true info string is returned by mysqli. You can easily patch your current code just by adding |
MariaDB version is reported differently between PHP versions: * PHP 8.0.16 or later: `10.6.8-MariaDB` * PHP 8.0.15 or earlier: `5.5.5-10.6.8-MariaDB` The latter includes PHP 7.4.x and PHP 5.6.x as well, where the version is also reported with the `5.5.5-` prefix. This commit makes an adjustment to the `Tests_DB_Charset` class to check for the correct version. References: * [php/php-src#7972 php-src: #7972: MariaDB version prefix 5.5.5- is not stripped] * [php/php-src#7963 php-src: PR #7963 Fix GH-7932: MariaDB version prefix not always stripped] Follow-up to [53918]. Fixes #53623. git-svn-id: https://develop.svn.wordpress.org/trunk@53919 602fd350-edb4-49c9-b593-d223f7449a82
MariaDB version is reported differently between PHP versions: * PHP 8.0.16 or later: `10.6.8-MariaDB` * PHP 8.0.15 or earlier: `5.5.5-10.6.8-MariaDB` The latter includes PHP 7.4.x and PHP 5.6.x as well, where the version is also reported with the `5.5.5-` prefix. This commit makes an adjustment to the `Tests_DB_Charset` class to check for the correct version. References: * [php/php-src#7972 php-src: #7972: MariaDB version prefix 5.5.5- is not stripped] * [php/php-src#7963 php-src: PR #7963 Fix GH-7932: MariaDB version prefix not always stripped] Follow-up to [53918]. Fixes #53623. Built from https://develop.svn.wordpress.org/trunk@53919 git-svn-id: http://core.svn.wordpress.org/trunk@53478 1a063a9b-81f0-0310-95a4-ce76da25c4cd
MariaDB version is reported differently between PHP versions: * PHP 8.0.16 or later: `10.6.8-MariaDB` * PHP 8.0.15 or earlier: `5.5.5-10.6.8-MariaDB` The latter includes PHP 7.4.x and PHP 5.6.x as well, where the version is also reported with the `5.5.5-` prefix. This commit makes an adjustment to the `Tests_DB_Charset` class to check for the correct version. References: * [php/php-src#7972 php-src: #7972: MariaDB version prefix 5.5.5- is not stripped] * [php/php-src#7963 php-src: PR #7963 Fix GH-7932: MariaDB version prefix not always stripped] Follow-up to [53918]. Fixes #53623. Built from https://develop.svn.wordpress.org/trunk@53919 git-svn-id: https://core.svn.wordpress.org/trunk@53478 1a063a9b-81f0-0310-95a4-ce76da25c4cd
MariaDB version is reported differently between PHP versions: * PHP 8.0.16 or later: `10.6.8-MariaDB` * PHP 8.0.15 or earlier: `5.5.5-10.6.8-MariaDB` The latter includes PHP 7.4.x and PHP 5.6.x as well, where the version is also reported with the `5.5.5-` prefix. This commit makes an adjustment to the `Tests_DB_Charset` class to check for the correct version. References: * [php/php-src#7972 php-src: #7972: MariaDB version prefix 5.5.5- is not stripped] * [php/php-src#7963 php-src: PR #7963 Fix GH-7932: MariaDB version prefix not always stripped] Follow-up to [53918]. Fixes #53623. git-svn-id: https://develop.svn.wordpress.org/trunk@53919 602fd350-edb4-49c9-b593-d223f7449a82
MariaDB version is reported differently between PHP versions: * PHP 8.0.16 or later: `10.6.8-MariaDB` * PHP 8.0.15 or earlier: `5.5.5-10.6.8-MariaDB` The latter includes PHP 7.4.x and PHP 5.6.x as well, where the version is also reported with the `5.5.5-` prefix. This commit makes an adjustment to the `Tests_DB_Charset` class to check for the correct version. References: * [php/php-src#7972 php-src: #7972: MariaDB version prefix 5.5.5- is not stripped] * [php/php-src#7963 php-src: PR #7963 Fix GH-7932: MariaDB version prefix not always stripped] Follow-up to [53918]. Fixes #53623. Built from https://develop.svn.wordpress.org/trunk@53919
MariaDB version is reported differently between PHP versions: * PHP 8.0.16 or later: `10.6.8-MariaDB` * PHP 8.0.15 or earlier: `5.5.5-10.6.8-MariaDB` The latter includes PHP 7.4.x and PHP 5.6.x as well, where the version is also reported with the `5.5.5-` prefix. This commit makes an adjustment to `wpdb::has_cap()` to check for the correct MariaDB version. This resolves an issue where the `utf8mb4_unicode_520_ci` collation, which is available in MariaDB since version 10.2, was previously not detected correctly. References: * [php/php-src#7972 php-src: #7972: MariaDB version prefix 5.5.5- is not stripped] * [php/php-src#7963 php-src: PR #7963 Fix GH-7932: MariaDB version prefix not always stripped] * [https://mariadb.com/docs/reference/mdb/collations/utf8mb4_unicode_520_ci/ MariaDB Documentation: utf8mb4_unicode_520_ci] Follow-up to [37523], [53919]. Props jamieburchell, SergeyBiryukov. Fixes #54841. Built from https://develop.svn.wordpress.org/trunk@54384 git-svn-id: http://core.svn.wordpress.org/trunk@53943 1a063a9b-81f0-0310-95a4-ce76da25c4cd
MariaDB version is reported differently between PHP versions: * PHP 8.0.16 or later: `10.6.8-MariaDB` * PHP 8.0.15 or earlier: `5.5.5-10.6.8-MariaDB` The latter includes PHP 7.4.x and PHP 5.6.x as well, where the version is also reported with the `5.5.5-` prefix. This commit makes an adjustment to `wpdb::has_cap()` to check for the correct MariaDB version. This resolves an issue where the `utf8mb4_unicode_520_ci` collation, which is available in MariaDB since version 10.2, was previously not detected correctly. References: * [php/php-src#7972 php-src: #7972: MariaDB version prefix 5.5.5- is not stripped] * [php/php-src#7963 php-src: PR #7963 Fix GH-7932: MariaDB version prefix not always stripped] * [https://mariadb.com/docs/reference/mdb/collations/utf8mb4_unicode_520_ci/ MariaDB Documentation: utf8mb4_unicode_520_ci] Follow-up to [37523], [53919]. Props jamieburchell, SergeyBiryukov. Fixes #54841. Built from https://develop.svn.wordpress.org/trunk@54384 git-svn-id: https://core.svn.wordpress.org/trunk@53943 1a063a9b-81f0-0310-95a4-ce76da25c4cd
MariaDB version is reported differently between PHP versions: * PHP 8.0.16 or later: `10.6.8-MariaDB` * PHP 8.0.15 or earlier: `5.5.5-10.6.8-MariaDB` The latter includes PHP 7.4.x and PHP 5.6.x as well, where the version is also reported with the `5.5.5-` prefix. This commit makes an adjustment to the `Tests_DB_Charset` class to check for the correct version. References: * [php/php-src#7972 php-src: #7972: MariaDB version prefix 5.5.5- is not stripped] * [php/php-src#7963 php-src: PR #7963 Fix GH-7932: MariaDB version prefix not always stripped] Follow-up to [53918]. Fixes #53623. git-svn-id: https://develop.svn.wordpress.org/trunk@53919 602fd350-edb4-49c9-b593-d223f7449a82
MariaDB version is reported differently between PHP versions: * PHP 8.0.16 or later: `10.6.8-MariaDB` * PHP 8.0.15 or earlier: `5.5.5-10.6.8-MariaDB` The latter includes PHP 7.4.x and PHP 5.6.x as well, where the version is also reported with the `5.5.5-` prefix. This commit makes an adjustment to `wpdb::has_cap()` to check for the correct MariaDB version. This resolves an issue where the `utf8mb4_unicode_520_ci` collation, which is available in MariaDB since version 10.2, was previously not detected correctly. References: * [php/php-src#7972 php-src: #7972: MariaDB version prefix 5.5.5- is not stripped] * [php/php-src#7963 php-src: PR #7963 Fix GH-7932: MariaDB version prefix not always stripped] * [https://mariadb.com/docs/reference/mdb/collations/utf8mb4_unicode_520_ci/ MariaDB Documentation: utf8mb4_unicode_520_ci] Follow-up to [37523], [53919]. Props jamieburchell, SergeyBiryukov. Fixes #54841. git-svn-id: https://develop.svn.wordpress.org/trunk@54384 602fd350-edb4-49c9-b593-d223f7449a82
For consistency with
mysqlnd_conn_data#get_server_version
, we stripthe MariaDB version prefix also in
mysqlnd_command#handshake
.The definition of
MARIA_DB_VERSION_HACK_PREFIX
should better go into a header (maybe mysqlnd_portability.h), but since all mysqlnd headers are installed, we better delay that for master to avoid compatibility issues.@kamil-tekiela, what do you think? The alternative would be to remove the stripping in
mysqlnd_conn_data#get_server_version
, but that would bring back https://bugs.php.net/78179.