feat: implement MariaDbOperationService and add optimized MariaDB configuration template
This commit is contained in:
@@ -7,13 +7,15 @@ character-set-server=utf8mb4
|
|||||||
collation-server=utf8mb4_unicode_ci
|
collation-server=utf8mb4_unicode_ci
|
||||||
log-error="{{LOG_FILE}}"
|
log-error="{{LOG_FILE}}"
|
||||||
|
|
||||||
# Performance Optimizations
|
# Performance & Scale Optimizations
|
||||||
max_allowed_packet=1G
|
max_allowed_packet=1G
|
||||||
innodb_buffer_pool_size=512M
|
innodb_buffer_pool_size=1G
|
||||||
innodb_log_file_size=128M
|
innodb_log_file_size=256M
|
||||||
innodb_flush_log_at_trx_commit=2
|
innodb_flush_log_at_trx_commit=2
|
||||||
innodb_doublewrite=0
|
innodb_doublewrite=0
|
||||||
innodb_lock_wait_timeout=600
|
innodb_lock_wait_timeout=600
|
||||||
|
innodb_strict_mode=0
|
||||||
|
innodb_default_row_format=DYNAMIC
|
||||||
|
|
||||||
[client]
|
[client]
|
||||||
port={{PORT}}
|
port={{PORT}}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import path from 'path'
|
|||||||
import { spawn } from 'child_process'
|
import { spawn } from 'child_process'
|
||||||
import decompress from 'decompress'
|
import decompress from 'decompress'
|
||||||
import zlib from 'zlib'
|
import zlib from 'zlib'
|
||||||
|
import { pipeline, PassThrough } from 'stream'
|
||||||
|
|
||||||
export interface MariaDbConfig {
|
export interface MariaDbConfig {
|
||||||
binPath: string
|
binPath: string
|
||||||
@@ -130,7 +131,8 @@ export class MariaDbOperationService {
|
|||||||
`--host=${config.host}`,
|
`--host=${config.host}`,
|
||||||
`--port=${config.port}`,
|
`--port=${config.port}`,
|
||||||
`--user=${config.rootUser}`,
|
`--user=${config.rootUser}`,
|
||||||
`--database=${dbName}`
|
`--database=${dbName}`,
|
||||||
|
'--max_allowed_packet=1G'
|
||||||
]
|
]
|
||||||
|
|
||||||
if (config.rootPass) {
|
if (config.rootPass) {
|
||||||
@@ -139,50 +141,48 @@ export class MariaDbOperationService {
|
|||||||
|
|
||||||
onProgress?.(`Executing: "${mariaDbPath}" ${args.join(' ')} < "${sqlFilePath}"`)
|
onProgress?.(`Executing: "${mariaDbPath}" ${args.join(' ')} < "${sqlFilePath}"`)
|
||||||
|
|
||||||
const child = spawn(mariaDbPath, args, { windowsHide: true })
|
const child = spawn(mariaDbPath, args, { windowsHide: true, stdio: ['pipe', 'pipe', 'pipe'] })
|
||||||
|
|
||||||
|
// Create a wrapper stream to prepend/append SQL commands
|
||||||
|
const combinedStream = new PassThrough()
|
||||||
|
|
||||||
|
// Send optimization headers
|
||||||
|
combinedStream.write('SET GLOBAL innodb_strict_mode = 0;\n')
|
||||||
|
combinedStream.write('SET SESSION innodb_strict_mode = 0;\n')
|
||||||
|
combinedStream.write('SET foreign_key_checks = 0;\n')
|
||||||
|
combinedStream.write('SET unique_checks = 0;\n')
|
||||||
|
combinedStream.write('SET autocommit = 0;\n')
|
||||||
|
combinedStream.write('SET sql_log_bin = 0;\n')
|
||||||
|
|
||||||
// Pipe the file content to stdin
|
|
||||||
const fileStream = fs.createReadStream(sqlFilePath)
|
const fileStream = fs.createReadStream(sqlFilePath)
|
||||||
|
|
||||||
// Performance optimizations
|
// Use pipeline for robust error handling and backpressure
|
||||||
child.stdin.write('SET foreign_key_checks = 0;\n')
|
pipeline(
|
||||||
child.stdin.write('SET unique_checks = 0;\n')
|
fileStream,
|
||||||
child.stdin.write('SET autocommit = 0;\n')
|
combinedStream,
|
||||||
child.stdin.write('SET sql_log_bin = 0;\n')
|
child.stdin,
|
||||||
|
(err) => {
|
||||||
fileStream.on('error', (err) => {
|
if (err) {
|
||||||
onProgress?.(`File read error: ${err.message}`)
|
if (err.code === 'EPIPE' || err.code === 'ECONNRESET') {
|
||||||
})
|
onProgress?.(`Notice: Pipe closed early (${err.code}). This is often normal if MariaDB finished early.`)
|
||||||
|
} else if (err.code === 'ENOBUFS') {
|
||||||
fileStream.on('data', (chunk) => {
|
onProgress?.(`Error: System buffer overflow (ENOBUFS). The file might be too large for current system limits.`)
|
||||||
if (child.stdin.writable) {
|
|
||||||
try {
|
|
||||||
child.stdin.write(chunk)
|
|
||||||
} catch (e: any) {
|
|
||||||
if (e.code === 'EPIPE') {
|
|
||||||
onProgress?.(`Warning: EPIPE error encountered. The child process may have closed the pipe early.`)
|
|
||||||
} else {
|
} else {
|
||||||
throw e
|
onProgress?.(`Stream error: ${err.message}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
|
|
||||||
|
// When file ends, send footer
|
||||||
fileStream.on('end', () => {
|
fileStream.on('end', () => {
|
||||||
if (child.stdin.writable) {
|
// Ensure we don't write to a closed stream
|
||||||
child.stdin.write('\nCOMMIT;\n')
|
if (!combinedStream.writableEnded) {
|
||||||
child.stdin.write('SET foreign_key_checks = 1;\n')
|
combinedStream.write('\nCOMMIT;\n')
|
||||||
child.stdin.write('SET unique_checks = 1;\n')
|
combinedStream.write('SET foreign_key_checks = 1;\n')
|
||||||
child.stdin.write('SET autocommit = 1;\n')
|
combinedStream.write('SET unique_checks = 1;\n')
|
||||||
child.stdin.end()
|
combinedStream.write('SET autocommit = 1;\n')
|
||||||
}
|
combinedStream.end()
|
||||||
})
|
|
||||||
|
|
||||||
child.stdin.on('error', (err: any) => {
|
|
||||||
if (err.code === 'EPIPE') {
|
|
||||||
onProgress?.(`Notice: Broken pipe (EPIPE). This usually means MariaDB finished or aborted before we finished writing.`)
|
|
||||||
} else {
|
|
||||||
onProgress?.(`Stdin error: ${err.message}`)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user