fix(db): fix startup on broken db after hardware shutdown #43

This commit is contained in:
Alexey Kasyanchuk
2018-07-13 01:48:13 +03:00
parent fce0d0b275
commit 1f7ff446cc
2 changed files with 56 additions and 0 deletions

View File

@ -0,0 +1,3 @@
const glob = require("glob")
module.exports = (path) => new Promise((resolve) => glob(path, (error, files) => resolve(files)))

View File

@ -8,6 +8,8 @@ const fs = require('fs')
const iconv = require('iconv-lite') const iconv = require('iconv-lite')
const { spawn, exec } = require('child_process') const { spawn, exec } = require('child_process')
const appConfig = require('./config') const appConfig = require('./config')
const findFiles = require('./findFiles')
const _ = require('lodash')
const writeSphinxConfig = (path, dbPath) => { const writeSphinxConfig = (path, dbPath) => {
let config = ` let config = `
@ -173,12 +175,22 @@ module.exports = (callback, dataDirectory, onClose) => {
sphinx.stdout.on('data', (data) => { sphinx.stdout.on('data', (data) => {
console.log(`sphinx: ${data}`) console.log(`sphinx: ${data}`)
// don't listen if we are in fixing mode
if(sphinx.fixing)
return
if (data.includes('accepting connections')) { if (data.includes('accepting connections')) {
console.log('catched sphinx start') console.log('catched sphinx start')
if(callback) if(callback)
callback() callback()
} }
if(data.includes('invalid meta file'))
{
sphinx.fixDatabase()
}
const checkOptimized = String(data).match(/index ([\w]+): optimized/) const checkOptimized = String(data).match(/index ([\w]+): optimized/)
if(checkOptimized) if(checkOptimized)
{ {
@ -214,6 +226,47 @@ module.exports = (callback, dataDirectory, onClose) => {
} }
}) })
sphinx.fixDatabase = async () => {
if(sphinx.fixing)
return
sphinx.fixing = true
// close db
await new Promise((resolve) => {
sphinx.stop(resolve, true)
console.log('revent start')
})
const checkNullFile = (file) => new Promise((resolve) => {
let f = fs.createReadStream(file)
f.on('data', (chunk) => {
for(const byte of chunk)
if(byte != 0)
{
resolve(true)
f.destroy()
return
}
}).on('end', () => {
resolve(false)
});
})
// check meta files
const probablyCoruptedFiles = await findFiles(`${sphinx.directoryPath}/**/*.+(meta|ram)`)
let brokenFiles = await Promise.all(probablyCoruptedFiles.map(file => checkNullFile(file)))
brokenFiles = probablyCoruptedFiles.filter((file, index) => !brokenFiles[index])
brokenFiles.forEach(file => {
console.log('FIXDB: clean file because of broken', file)
fs.unlinkSync(file)
})
sphinx.fixing = false
_.merge(sphinx, sphinx.start(callback));
}
return sphinx return sphinx
} }