-
-
Notifications
You must be signed in to change notification settings - Fork 2.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
TPROD-182 Dynamic database platform detection #9739
TPROD-182 Dynamic database platform detection #9739
Conversation
90c8635
to
b1fab2d
Compare
b1fab2d
to
7d5b456
Compare
Codecov Report
@@ Coverage Diff @@
## features #9739 +/- ##
==============================================
+ Coverage 41.31% 41.37% +0.05%
- Complexity 34560 34563 +3
==============================================
Files 2060 2061 +1
Lines 111520 111520
==============================================
+ Hits 46079 46139 +60
+ Misses 65441 65381 -60
|
4266ac3
to
b53317c
Compare
This is now ready to test. Just updated the PR description with more details and background on the changes I made. Since this is a BC break, let's try to have it included in the Mautic 4 beta release! |
@@ -59,7 +67,7 @@ public function getPhpInfo() | |||
return $this->phpInfo; | |||
} | |||
|
|||
if (function_exists('phpinfo')) { | |||
if (function_exists('phpinfo') && 'cli' !== php_sapi_name()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is needed because when PHP is running on the CLI (e.g. during automated tests), phpinfo()
doesn't render HTML but regular text + line breaks instead. Then the logic within this if
block breaks. This doesn't change any existing behavior for "normal" users, and the formatting is updated in the UI as it was before.
@@ -1177,7 +1177,7 @@ | |||
'db_user' => '', | |||
'db_password' => '', | |||
'db_table_prefix' => '', | |||
'db_server_version' => '5.7', | |||
'db_server_version' => defined('MAUTIC_DB_NOT_CONFIGURED') ? '5.7' : null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a crucial part of the logic. When no config/local.php
has been created yet, MAUTIC_DB_NOT_CONFIGURED
is defined. See PR description for more details.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alanhartless I might need some help here. As correctly indicated by @RCheesley from her testing, the db_server_version
parameter is still being written to config/local.php
this way. Earlier on in my journey for this PR, I removed db_server_version
from CoreBundle/Config/config.php
and added the logic to app/config/config.php
, here:
Line 117 in c6b7ae7
'server_version' => '%mautic.db_server_version%', |
However that seems to write the value into Symfony's cache, which we also don't want. Because otherwise it remains at 5.7
even after installation, until folks remove their cache. Is there a way to dynamically get the value from db_server_version
here (as it does now) while preventing it from being written to config/local.php
? That's the final missing piece in this PR then!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Idea: we might be able to leverage MAUTIC_CONFIG_PARAMETERS
for this (I couldn't find any documentation about that env variable by the way, but looking at the code we might be able to set/update it to {"db_server_version": "5.7"}
in the AppKernel, instead of setting that constant). That way, we can remove db_server_version
from CoreBundle/Config/config.php
and it won't be stored in config/local.php
anymore 🚀
I'll test this theory later today
mautic/app/bundles/CoreBundle/Loader/ParameterLoader.php
Lines 160 to 166 in 7dbb6ee
// Load from environment | |
$envParameters = getenv('MAUTIC_CONFIG_PARAMETERS'); | |
if ($envParameters) { | |
$compiledParameters = array_merge($compiledParameters, json_decode($envParameters, true)); | |
} | |
$this->localParameters = $compiledParameters; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FIXED IN 9f8bc8a 🎉 🚀 CC @RCheesley @alanhartless
@@ -82,29 +82,35 @@ public function loadIntoEnvironment() | |||
$dotenv->populate($envVariables->all()); | |||
} | |||
|
|||
public static function getLocalConfigFile(string $root): string | |||
public static function getLocalConfigFile(string $root, $updateDefaultParameters = true): string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$updateDefaultParameters
is needed because once one or more keys are set in $defaultParameters
, the loadDefaultParameters()
function doesn't work anymore because it thinks that all default parameters have already been set:
mautic/app/bundles/CoreBundle/Loader/ParameterLoader.php
Lines 110 to 116 in c806115
private function loadDefaultParameters(): void | |
{ | |
if (self::$defaultParameters) { | |
// This is loaded within and outside the container so use static variable to prevent recompiling | |
// multiple times | |
return; | |
} |
Since we only access getLocalConfigFile()
in the AppKernel
, and not any other config files or env variables, we want to prevent $defaultParameters
from being set incompletely on application boot. Therefore we explicitly set $updateDefaultParameters
to false
when accessing this function from the AppKernel, since we simply need to get the path to our local config file from there.
I guess the alternative instead of changing this function is to simply look for $root/config/local.php
in the AppKernel
, but I'm not sure if that reliably covers all possible scenarios for service providers that might use custom paths to their config files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
Load up this PR locally ✅
-
Ensure Mautic's installer works correctly (ideally try both with MariaDB ✅ and MySQL ✅ , and both UI ✅ + CLI ✅ installations)
-
Check if the "database info" tab works as expected under System info > Database info ✅ MySQL ✅ MariaDB
-
Run php bin/console doctrine:schema:update --dump-sql, it should return less than 10 queries to be executed ✅ one query for MariaDB and one for MySQL
-
Try to do a clean installation based on the features branch. Ensure your app/config/local.php has a db_server_version parameter (if it doesn't show up right away, go to Configuration in Mautic's UI and hit Save) ❓ it has the param but it is
'db_server_version' => null
on MySQL and was set to'db_server_version' => '5.7'
on MariaDB - which confused me somewhat! -
Then checkout this PR and run php bin/console doctrine:migrations:execute --up 20210502162314. The db_server_version parameter should now be removed from your app/config/local.php file. ✅ MySQL and ✅ MariaDB
So other than the query on point 5 @dennisameling this is an approve - can you clarify?
@RCheesley the value of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested this PR with MariaDB and Mysql, it worked as expected.
- Only migration was showing
- In the system info I was able to see the database information
local.php
was adjusted as mentioned
@dennisameling just ran through it again - in both cases (MySQL and MariaDB) there is With both cases it is removed after I apply the migration now, the DB info is showing in the system info correctly. |
@RCheesley Yes that's correct - this PR prevents the hardcoded version from being written to the |
Awesome! Just needs a code review then from @mautic/core-team and we are good to go! |
@@ -1177,7 +1181,6 @@ | |||
'db_user' => '', | |||
'db_password' => '', | |||
'db_table_prefix' => '', | |||
'db_server_version' => '5.7', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This prevents the db_server_version
from being written to app/config/local.php
moving forward 🚀
|
||
use Symfony\Component\DependencyInjection\EnvVarProcessorInterface; | ||
|
||
class MauticConstProcessor implements EnvVarProcessorInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needed a custom env var processor because Symfony's built-in const
processor didn't seem to work as expected https://symfony.com/doc/current/configuration/env_var_processors.html#built-in-environment-variable-processors
We use this in the code as %env(mauticconst:MAUTIC_DB_SERVER_VERSION)%
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not finding anything that jumps out to me as concerning with this. One small note of a newly added variable that I don't see used anywhere so not sure if that is needed. I think it's good to go with tests. I'd expect there is some risk as more environments are tested with the code but we'll have to deal with those as they come.
$configParameterBag = (new \Mautic\CoreBundle\Loader\ParameterLoader())->getParameterBag(); | ||
$parameterLoader = new \Mautic\CoreBundle\Loader\ParameterLoader(); | ||
$configParameterBag = $parameterLoader->getParameterBag(); | ||
$localConfigParameterBag = $parameterLoader->getLocalParameterBag(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this used anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dennisameling can you follow up on this question at a later date? Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works for me 👍 Nice PR
I tested new installation, I tested current installation + migrations.
Without issue.
Let's merge it and try tested in RC
This pull request has been mentioned on Mautic Community Forums. There might be relevant details there: https://forum.mautic.org/t/out-of-the-blue-dba-exception-mautic-down/22858/7 |
This pull request has been mentioned on Mautic Community Forums. There might be relevant details there: https://forum.mautic.org/t/out-of-the-blue-dba-exception-mautic-down/22858/21 |
Hi @RCheesley @dennisameling take if (!defined('MAUTIC_DB_SERVER_VERSION')) {
$localConfigFile = ParameterLoader::getLocalConfigFile($this->getRootDir(), false);
define('MAUTIC_DB_SERVER_VERSION', file_exists($localConfigFile) ? null : '5.7');
} evaluates to null which is worse than 5.7. if you already have a local config file - where you may be willing to declare the constant - you can not. the value of this constant is used in 'server_version' => '%env(mauticconst:MAUTIC_DB_SERVER_VERSION)%', while all other DB related configuration is declared this way: 'driver' => '%mautic.db_driver%',
'host' => '%mautic.db_host%',
'port' => '%mautic.db_port%',
'dbname' => '%mautic.db_name%',
'user' => '%mautic.db_user%',
'password' => '%mautic.db_password%',
'charset' => 'utf8mb4', etc. at my end this forces the platform autodetection which also keeps and extra open connection. that makes on very few requests very much open connections. am I getting it wrong or will the |
@galvani @dennisameling not working anymore for Mautic.
|
Description
Mautic currently has a hardcoded
server_version
config parameter, set to '5.7'. However, this is problematic for a few reasons:server_version
is hardcoded and the database type is MariaDB, it needs to be prefixed bymariadb-{VERSION}
, so that Doctrine knows it's MariaDB. Mautic currently doesn't do this, so Doctrine always thinks it's interacting with MySQL.config/local.php
file, so without a migration it won't be updated automatically if Mautic's minimal database version requirement changes. This has led to problems before; see Bump minimum MySQL version to 5.7 #9437 as an example.Since version 2.5, Doctrine has automatic platform version detection built-in. So it will recognize if e.g. the minimum MySQL version is 5.7, required for some functionality that was only added in version 5.7.
As far as I know, there's no need (anymore) for Mautic to hardcode the database server version, hence this PR.
This PR also adds a new tab "Database info" to the "System info" page for easier debugging/troubleshooting:
Why database auto-detection is tricky in the installer
When Mautic isn't installed yet, you'll get an exception in the installer when no explicit
server_version
is set:This was already reported by @alanhartless to the Doctrine team in 2015, with no good fix for Mautic's use case to date.
The good news is that we can set a
server_version
manually in the installer, until the database credentials are set. The order of steps is as follows then:server_version
to5.7
in the installerinstallSchema()
below)This order of steps is crucial. During my testing, before I had a fix for this in place, the detected database platform remained
MySQL
and it stayed like that until I removed the cache. In order to prevent issues in the future, we want step 3 (switch to automatic platform detection before installing the schema) to happen first.I came up with a somewhat ugly fix for this in the
AppKernel
by setting a constant calledMAUTIC_DB_NOT_CONFIGURED
that the installer can recognize. That way it knows exactly when to switch over to automatic database platform detection.Step 1.0 in the installer (user sets database credentials):
Step 1.1 in the installer (Mautic now switches to automatic database platform detection, prior to installing the schema):
During schema installation, the correct database platform (MariaDB in this case) is indeed detected:
Steps to test this PR:
System info > Database info
php bin/console doctrine:schema:update --dump-sql
, it should return less than 10 queries to be executedfeatures
branch. Ensure yourapp/config/local.php
has adb_server_version
parameter (if it doesn't show up right away, go to Configuration in Mautic's UI and hit Save). Then checkout this PR and runphp bin/console doctrine:migrations:execute --up 20210502162314
. Thedb_server_version
parameter should now be removed from yourapp/config/local.php
file.