MediaWiki database policy

From MediaWiki.org
Jump to navigation Jump to search

This page describes the official database policy for MediaWiki code. It was approved in December 2019 via the TechCom RFC process per RFC T220056.

Database queries[edit]

  • All new code that sends SQL queries from MediaWiki must not generate any warning under MariaDB/MySQL's strict mode (per RFC T112637).
    • WMF will be enabling MariaDB/MySQL's strict mode (T108255), which will be the default anyway in MySQL 5.7. Prior to this, code must be free of warnings.
    • Code that touches the database must be compatible with the following MySQL SQL modes:
      • TRADITIONAL (equivalent to STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER)
      • ONLY_FULL_GROUP_BY
  • Database code must be compatible with older versions of databases as listed in the MediaWiki installation requirements for database server. However, performance improvements that would only apply to the newest, supported versions (or its default or widely recommended defaults) should be favoured over those that apply only to unsupported releases.
  • Non-deterministic queries and unsafe statements for binlog should be avoided as they would return/write different results in a replication environment. The latter can be detected as warnings with the text "[Warning] Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT". Those include INSERT ... SELECT when using an auto_increment key, UPDATE ... LIMIT without an ORDER BY, and using non-deterministic functions like SYSDATE(). https://dev.mysql.com/doc/refman/5.6/en/replication-rbr-safe-unsafe.html has more info

Schema changes[edit]

  • All new tables must have a primary key. When a candidate for primary key could not be created (for example, if all columns can be repeated), a separate auto_increment column, or other arbitrary field (depending on the case), must be added.
  • Primary keys, and fields that reference them, should be unsigned, in order to increase the maximum values.

Database patches[edit]

If you change the database schema, follow these rules:

  • Update the installer – Update includes/installer and add an appropriate SQL patch file to maintenance/archives/. The naming convention, if you're adding a field, is patch-{table}-{field}.sql. If you're removing a field, it's patch-drop-{table}-{field}.sql. If you're adding a table, it's patch-{table}.sql. Look at the commit history of includes/installer/(MySQL|Postgres|SQLite)Updater.php to find examples of how it's done. If you're adding a bunch of fields to the same table, make all those changes in one query in one patch file.
  • Make your schema change optional – All schema changes must go through a period of being optional. Some examples:
    • Instead of changing the format of a column, create a new column, make all writes happen to the old and new column (if it exists), and deprecate use of the old column. Check if the new column exists before blindly assuming that it does. Only eliminate support for the old column after it's clear the schema migration has completed and there's no chance that we'll need to roll back to the old version of the software. If this doesn't seem feasible, send mail to Wikitech-l asking for advice.
    • You could set your new feature to only work if a config option is set to true, and set the option to false by default. Then the commit can be safely deployed before the schema change is made. To deploy your feature to the Wikimedia cluster, file a ticket in Phabricator in the relevant project with the #schema-change tag. Once you've confirmed the change has been made, you can remove the config option to enable your feature.
    • Note that this means your schema change should be optional in code - for wikimedia deployments, it is expected that every wiki with the relevant database table(s) will have the schema change applied to them. If you need different schema for different wikis, then apply the change using an extension and creating new tables dependent on that extension.

There might be cases where the "make your schema change optional" rule will be prohibitive from a performance or logistics perspective. However, schema changes like that should be rare to begin with, and should have prominent discussion on the wikitech-l mailing list. In the case where it's impossible to make your schema change optional, it is still critical to write scripts to roll back to the pre-change state.

  • Search for input from a WMF Database Administrator – MediaWiki is deployed to Wikimedia websites every week, and it takes considerable planning to apply schema changes to MySQL-based sites the size of Wikipedia. As of September 2017, Jaime Crespo (jcrespo on LDAP, jynus on irc and Manuel Arostegui, marostegui) are the best people to add to database reviews. In most cases, input is just needed on the logistics of the change.
  • Test your changes on Beta - in particular, it is a common mistake to change indexes and column definitions that would result in different query plans. Try to test the generated queries' plan with tools such as EXPLAIN; not doing so could mean that, when scaled to production, queries that only take 1 second locally, they pileup on production when they receive much more traffic and have larger tables.