What is the installation canary?
What is the installation canary?


The civicrm_install_canary is fundamentally a test to see how well we control/understand the installation process. It's part of a bigger topic, so bear with me in giving the context.

The crux of the CiviCRM installation process has traditionally been two steps: 


Copy a config template and edit it (civicrm.settings.php.tpl => civicrm.settings.php).
Load a SQL file into the database (civicrm.mysql and either civicrm_data.mysql or civicrm_generated.mysql).


When you use tools like sites/all/modules/civicrm/install/index.php or the Joomla installer or setup.sh or civibuild or provision_civicrm, these are basically all wrappers which do those two steps (plus random-other-things).

There are several installation-related things which aren't addressed by those two standardized steps, leading to some pain-points, e.g.


System requirements are not enforced or communicated consistently across installers.
If you install from git (instead of .tar.gz or .zip), then you need to run extra commands (GenCode).
You cannot automatically activate CiviCRM extensions during installation.
SQL triggers are generated using PHP logic. (The triggers should be generated during installation... and also when setting up custom-data or extensions...)
If you want to use a different language, then you need to load localized .mysql files. The pre-generation process for this slows down developmental builds and produces slightly stale translations for users.
PHP's MySQL API's have become a bit hostile to pre-generating SQL files.


For a long time, changing this was blocked because we simply didn't have a reliable way to add PHP logic during all installations... until someone proposed that we could do a bit of install logic during the first page-request. Sometime (maybe 4.7.0?) we introduced SystemInstallEvent.

Originally, the only thing SystemInstallEvent did was prove its own validity. The event should fire exactly once. If it fires a second time, then that's an error. Specifically, the SystemInstallEvent triggers the InstallationCanary which creates the table civicrm_install_canary (and failing if it already exists).

Eventually, we added DatabaseInitializer which also listens for SystemInstallEvent. During the first page-request, it runs the System.flush to ensure that triggers, caches, etal are current.


  Does it mean that the installation has been failed irreparable, and that the backup must be restored.


The system is probably OK. If you're getting an error, here are a few things to know:


On a new system (before the first page-view), the expected pre-condition is that the setting installed is untrue/undefined. The table civicrm_install_canary does not exist.
On an active system (after the first page-view), the expected post-condition is that the setting installed is true. The table civicrm_install_canary does exist.
If your system satisfies either pre-condition or post-condition, then it should be fine. You only get an error from a mix.
You might want to do a system flush and enable triggers, e.g.


Using Drupal website: http://mysite.example.com/civicrm/clearcache?triggerRebuild=1
Using drush CLI: drush cvapi system.flush triggers=1
Using cv CLI: cv api system.flush triggers=1