0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-11 02:12:21 -05:00

Removed unnecessary checks during initial DB init

refs https://github.com/TryGhost/Toolbox/issues/202

- during DB init, we have to create all the tables
- right now we loop over all tables and call the `createTable` command
  - this command checks if the table exists and if not, creates the table
  - this works fine but it means we query the database for every table
  - in MySQL, we query the information_schema table, which we've seen
    issues with before because it doesn't have indexes
- the smarter thing to do here is to get all the tables that already exist,
  remove them from the list, and just straight up create them without
  further checks
- this entire thing should be protected by the migration lock so we
  shouldn't encounter issues from multiple processes initializing the DB
  and tables existing after the initial check
- this commit also removes the check from `createTable` because this isn't
  really needed. We should be using the migration utils, which do
  check for existing tables. I've added a note to the function and
  audited anywhere we still call the function
- this commit removes (- 49 tables + 1 initial check) 48 queries from
  the initial DB init
This commit is contained in:
Daniel Lockyer 2022-02-18 10:51:53 +01:00
parent 8c311419c6
commit ddaa4ee5e1
2 changed files with 23 additions and 21 deletions

View file

@ -7,7 +7,10 @@ const schemaTables = Object.keys(schema);
module.exports.up = async (options) => {
const connection = options.connection;
await Promise.mapSeries(schemaTables, async (table) => {
const existingTables = await commands.getTables(connection);
const missingTables = schemaTables.filter(t => !existingTables.includes(t));
await Promise.mapSeries(missingTables, async (table) => {
logging.info('Creating table: ' + table);
await commands.createTable(table, connection);
});

View file

@ -307,29 +307,28 @@ async function addPrimaryKey(tableName, columns, transaction) {
}
/**
* https://github.com/tgriesser/knex/issues/1303
* createTableIfNotExists can throw error if indexes are already in place
* Adds a table according to the provided spec, or falls back to the current schema
*
* NOTE: this function does NOT check if the table already exists - use the migration
* utils if you want that
*
* @param {String} table - name of the table to create
* @param {import('knex').Transaction} transaction - connection to the DB
* @param {Object} [tableSpec] - table schema to generate table with
*/
function createTable(table, transaction, tableSpec = schema[table]) {
return (transaction || db.knex).schema.hasTable(table)
.then(function (exists) {
if (exists) {
return;
}
return (transaction || db.knex).schema.createTable(table, function (t) {
Object.keys(tableSpec)
.filter(column => !(column.startsWith('@@')))
.forEach(column => addTableColumn(table, t, column, tableSpec[column]));
return (transaction || db.knex).schema.createTable(table, function (t) {
Object.keys(tableSpec)
.filter(column => !(column.startsWith('@@')))
.forEach(column => addTableColumn(table, t, column, tableSpec[column]));
if (tableSpec['@@INDEXES@@']) {
tableSpec['@@INDEXES@@'].forEach(index => t.index(index));
}
if (tableSpec['@@UNIQUE_CONSTRAINTS@@']) {
tableSpec['@@UNIQUE_CONSTRAINTS@@'].forEach(unique => t.unique(unique));
}
});
});
if (tableSpec['@@INDEXES@@']) {
tableSpec['@@INDEXES@@'].forEach(index => t.index(index));
}
if (tableSpec['@@UNIQUE_CONSTRAINTS@@']) {
tableSpec['@@UNIQUE_CONSTRAINTS@@'].forEach(unique => t.unique(unique));
}
});
}
function deleteTable(table, transaction) {