Speed up built-in db migration
This commit is contained in:
parent
b8f2b9f16c
commit
486183fe62
|
@ -7,6 +7,11 @@ async function up (utils: {
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
const { transaction } = utils
|
const { transaction } = utils
|
||||||
|
|
||||||
|
{
|
||||||
|
await utils.sequelize.query('DROP INDEX IF EXISTS "video_file_video_id"')
|
||||||
|
await utils.sequelize.query('DROP INDEX IF EXISTS "video_file_video_streaming_playlist_id"')
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
await utils.queryInterface.addColumn('videoFile', 'formatFlags', {
|
await utils.queryInterface.addColumn('videoFile', 'formatFlags', {
|
||||||
type: Sequelize.INTEGER,
|
type: Sequelize.INTEGER,
|
||||||
|
@ -14,9 +19,7 @@ async function up (utils: {
|
||||||
allowNull: false
|
allowNull: false
|
||||||
}, { transaction })
|
}, { transaction })
|
||||||
|
|
||||||
// Web videos
|
// Web videos will be updated in the migration script because the query can be slow
|
||||||
const query = 'UPDATE "videoFile" SET "formatFlags" = 1 WHERE "videoId" IS NOT NULL'
|
|
||||||
await utils.sequelize.query(query, { transaction })
|
|
||||||
|
|
||||||
await utils.queryInterface.changeColumn('videoFile', 'formatFlags', {
|
await utils.queryInterface.changeColumn('videoFile', 'formatFlags', {
|
||||||
type: Sequelize.INTEGER,
|
type: Sequelize.INTEGER,
|
||||||
|
|
|
@ -112,23 +112,6 @@ export enum ScopeNames {
|
||||||
@Table({
|
@Table({
|
||||||
tableName: 'videoFile',
|
tableName: 'videoFile',
|
||||||
indexes: [
|
indexes: [
|
||||||
{
|
|
||||||
fields: [ 'videoId' ],
|
|
||||||
where: {
|
|
||||||
videoId: {
|
|
||||||
[Op.ne]: null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fields: [ 'videoStreamingPlaylistId' ],
|
|
||||||
where: {
|
|
||||||
videoStreamingPlaylistId: {
|
|
||||||
[Op.ne]: null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
fields: [ 'infoHash' ]
|
fields: [ 'infoHash' ]
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import { ffprobePromise, getVideoStreamFPS } from '@peertube/peertube-ffmpeg'
|
import { ffprobePromise, getVideoStreamFPS } from '@peertube/peertube-ffmpeg'
|
||||||
import { VideoFileStream } from '@peertube/peertube-models'
|
import { VideoFileStream } from '@peertube/peertube-models'
|
||||||
import { initDatabaseModels } from '@server/initializers/database.js'
|
import { initDatabaseModels, sequelizeTypescript } from '@server/initializers/database.js'
|
||||||
import { buildFileMetadata } from '@server/lib/video-file.js'
|
import { buildFileMetadata } from '@server/lib/video-file.js'
|
||||||
import { VideoPathManager } from '@server/lib/video-path-manager.js'
|
import { VideoPathManager } from '@server/lib/video-path-manager.js'
|
||||||
import { VideoFileModel } from '@server/models/video/video-file.js'
|
import { VideoFileModel } from '@server/models/video/video-file.js'
|
||||||
import { VideoModel } from '@server/models/video/video.js'
|
import { VideoModel } from '@server/models/video/video.js'
|
||||||
import Bluebird from 'bluebird'
|
import Bluebird from 'bluebird'
|
||||||
import { pathExists } from 'fs-extra/esm'
|
import { pathExists } from 'fs-extra/esm'
|
||||||
|
import { QueryTypes } from 'sequelize'
|
||||||
|
|
||||||
run()
|
run()
|
||||||
.then(() => process.exit(0))
|
.then(() => process.exit(0))
|
||||||
|
@ -16,10 +17,47 @@ run()
|
||||||
})
|
})
|
||||||
|
|
||||||
async function run () {
|
async function run () {
|
||||||
console.log('## Assigning metadata information to local video files ##\n')
|
|
||||||
|
|
||||||
await initDatabaseModels(true)
|
await initDatabaseModels(true)
|
||||||
|
|
||||||
|
{
|
||||||
|
console.log('## Updating "formatFlags" column for web videos in "videoFile" table in database ##\n')
|
||||||
|
|
||||||
|
const totalQuery = 'SELECT COUNT(*) AS "total" FROM "videoFile" WHERE "videoId" IS NOT NULL AND "formatFlags" != 1'
|
||||||
|
const res = await sequelizeTypescript.query<{ total: string }>(totalQuery, { type: QueryTypes.SELECT as QueryTypes.SELECT })
|
||||||
|
const total = parseInt(res[0].total)
|
||||||
|
|
||||||
|
console.log(`Will update ${total.toLocaleString()} rows`)
|
||||||
|
|
||||||
|
if (total > 10000) {
|
||||||
|
console.log('Processing update in chunks because there are many rows to update...')
|
||||||
|
|
||||||
|
const chunkSize = 10000
|
||||||
|
let remaining = total
|
||||||
|
|
||||||
|
while (remaining > chunkSize) {
|
||||||
|
const before = new Date().getTime()
|
||||||
|
|
||||||
|
await sequelizeTypescript.query(
|
||||||
|
'UPDATE "videoFile" SET "formatFlags" = 1 WHERE id IN (' +
|
||||||
|
'SELECT id FROM "videoFile" WHERE "videoId" IS NOT NULL AND "formatFlags" != 1 LIMIT ' + chunkSize +
|
||||||
|
')'
|
||||||
|
)
|
||||||
|
|
||||||
|
remaining -= chunkSize
|
||||||
|
|
||||||
|
const ms = new Date().getTime() - before
|
||||||
|
console.log(`Processed ${chunkSize.toLocaleString()} rows in ${ms.toLocaleString()}ms. Remaining: ${remaining.toLocaleString()}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = 'UPDATE "videoFile" SET "formatFlags" = 1 WHERE "videoId" IS NOT NULL AND "formatFlags" != 1'
|
||||||
|
await sequelizeTypescript.query(query)
|
||||||
|
|
||||||
|
console.log('Rows updated!')
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('## Assigning metadata information to local video files ##\n')
|
||||||
|
|
||||||
const ids = await VideoModel.listLocalIds()
|
const ids = await VideoModel.listLocalIds()
|
||||||
|
|
||||||
await Bluebird.map(ids, async id => {
|
await Bluebird.map(ids, async id => {
|
||||||
|
|
Loading…
Reference in New Issue